[mono/llvm] [14 commits] 8dba3718: Add x86.sse2.pause intrinsic.

"Zoltan Varga ([email protected])" <[email protected]> Sat, 16 Nov 2013 13:40:55 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <00000142612491a3-e206bdc9-4beb-49b4-88af-0ff5b5b4d15e-000000@email.amazonses.com>
   Branch: refs/heads/mono4
     Home: https://github.com/mono/llvm
  Compare: https://github.com/mono/llvm/compare/8dba3718ef9d^...70f31ddf5041

   Commit: 8dba3718ef9d315ac25c630886ad6a3d0178898e
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:15:13 GMT
      URL: https://github.com/mono/llvm/commit/8dba3718ef9d315ac25c630886ad6a3d0178898e

Add x86.sse2.pause intrinsic.

Changed paths:
  M include/llvm/IR/IntrinsicsX86.td
  M lib/Target/X86/X86InstrSSE.td

Modified: include/llvm/IR/IntrinsicsX86.td
===================================================================
@@ -536,6 +536,7 @@ let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
               Intrinsic<[], [], []>;
   def int_x86_sse2_mfence : GCCBuiltin<"__builtin_ia32_mfence">,
               Intrinsic<[], [], []>;
+  def int_x86_sse2_pause : Intrinsic<[], []>;
 }
 
 //===----------------------------------------------------------------------===//

Modified: lib/Target/X86/X86InstrSSE.td
===================================================================
@@ -3499,7 +3499,7 @@ def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
 
 // Pause. This "instruction" is encoded as "rep; nop", so even though it
 // was introduced with SSE2, it's backward compatible.
-def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", [], IIC_SSE_PAUSE>, REP;
+def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", [(int_x86_sse2_pause)], IIC_SSE_PAUSE>, REP;
 
 // Load, store, and memory fence
 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),

   Commit: 2f888d23dff7ccc9ccee6ed6dc23e902bf00b329
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:15:24 GMT
      URL: https://github.com/mono/llvm/commit/2f888d23dff7ccc9ccee6ed6dc23e902bf00b329

Add a test for movfs on x86.

Changed paths:
  M test/CodeGen/X86/movfs.ll

Modified: test/CodeGen/X86/movfs.ll
===================================================================
@@ -4,5 +4,6 @@ define i32 @foo() nounwind readonly {
 entry:
 	%tmp = load i32* addrspace(257)* getelementptr (i32* addrspace(257)* inttoptr (i32 72 to i32* addrspace(257)*), i32 31)		; <i32*> [#uses=1]
 	%tmp1 = load i32* %tmp		; <i32> [#uses=1]
+	store i32 55, i32 addrspace(257)* getelementptr (i32 addrspace(257)* inttoptr (i32 72 to i32 addrspace(257)*), i32 32)
 	ret i32 %tmp1
 }

   Commit: 0ef4abaf72ba95fbb0b0de95cd7898b252fecbca
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:15:34 GMT
      URL: https://github.com/mono/llvm/commit/0ef4abaf72ba95fbb0b0de95cd7898b252fecbca

Avoid changing sqrt(nan) into undefined.

Changed paths:
  M lib/Analysis/ConstantFolding.cpp

Modified: lib/Analysis/ConstantFolding.cpp
===================================================================
@@ -1431,7 +1431,7 @@ static Constant *ConstantFoldConvertToInt(const APFloat &Val,
           return ConstantFoldFP(log10, V, Ty);
         else if (F->getIntrinsicID() == Intrinsic::sqrt &&
                  (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())) {
-          if (V >= -0.0)
+          if (V >= -0.0 || Op->getValueAPF().isNaN())
             return ConstantFoldFP(sqrt, V, Ty);
           else // Undefined
             return Constant::getNullValue(Ty);

   Commit: b992c1cf6d57cac203b5475d19656cc23c2c14b4
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:15:43 GMT
      URL: https://github.com/mono/llvm/commit/b992c1cf6d57cac203b5475d19656cc23c2c14b4

Add a 'mono' calling convention which allows us to pass an argument in a non-abi register.

Changed paths:
  M include/llvm-c/Core.h
  M include/llvm/IR/CallingConv.h
  M lib/Target/ARM/ARMBaseRegisterInfo.cpp
  M lib/Target/ARM/ARMCallingConv.td
  M lib/Target/ARM/ARMISelLowering.cpp
  M lib/Target/X86/X86CallingConv.td

Modified: include/llvm-c/Core.h
===================================================================
@@ -303,6 +303,7 @@
   LLVMColdCallConv        = 9,
   LLVMWebKitJSCallConv    = 12,
   LLVMAnyRegCallConv      = 13,
+  LLVMMono1CallConv       = 14,
   LLVMX86StdcallCallConv  = 64,
   LLVMX86FastcallCallConv = 65
 } LLVMCallConv;

Modified: include/llvm/IR/CallingConv.h
===================================================================
@@ -58,6 +58,9 @@
     // stackmap and patchpoint intrinsics).
     AnyReg = 13,
 
+    // Mono - Calling convention used by Mono
+    Mono = 14,
+
     // Target - This is the start of the target-specific calling conventions,
     // e.g. fastcall and thiscall on X86.
     FirstTargetCC = 64,

Modified: lib/Target/ARM/ARMBaseRegisterInfo.cpp
===================================================================
@@ -129,6 +129,14 @@
   // Some targets reserve R9.
   if (STI.isR9Reserved())
     Reserved.set(ARM::R9);
+
+  const Function *F = MF.getFunction();
+  if (F && F->getCallingConv() == CallingConv::Mono)
+    // FIXME: This is required for some reason, otherwise llvm treats R8 as a callee-saved registers
+    // even if we exclude it in getCalleeSavedRegs (). Luckily, R8 can still be used for argument
+    // passing even if it is 'reserved'.
+    Reserved.set(ARM::R8);
+
   // Reserve D16-D31 if the subtarget doesn't support them.
   if (!STI.hasVFP3() || STI.hasD16()) {
     assert(ARM::D31 == ARM::D16 + 15);

Modified: lib/Target/ARM/ARMCallingConv.td
===================================================================
@@ -186,6 +186,28 @@ def RetCC_ARM_AAPCS_VFP : CallingConv<[
 ]>;
 
 //===----------------------------------------------------------------------===//
+// ARM Mono calling conventions
+//===----------------------------------------------------------------------===//
+
+def CC_ARM_Mono_APCS : CallingConv<[
+
+  // Mono marks the parameter it wants to pass in this non-abi register with
+  // the 'inreg' attribute.
+  CCIfInReg<CCAssignToReg<[R8]>>,
+
+  CCDelegateTo<CC_ARM_APCS>
+]>;
+
+def CC_ARM_Mono_AAPCS : CallingConv<[
+
+  // Mono marks the parameter it wants to pass in this non-abi register with
+  // the 'inreg' attribute.
+  CCIfInReg<CCAssignToReg<[R8]>>,
+
+  CCDelegateTo<CC_ARM_AAPCS>
+]>;
+
+//===----------------------------------------------------------------------===//
 // Callee-saved register lists.
 //===----------------------------------------------------------------------===//
 

Modified: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
@@ -1302,6 +1302,15 @@ CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
     return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
   case CallingConv::GHC:
     return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
+  case CallingConv::Mono:
+    if (Return) {
+      return CCAssignFnForNode(CallingConv::C, true, isVarArg);
+    } else {
+      if (Subtarget->isAAPCS_ABI())
+        return CC_ARM_Mono_AAPCS;
+      else
+        return CC_ARM_Mono_APCS;
+    }
   }
 }
 

Modified: lib/Target/X86/X86CallingConv.td
===================================================================
@@ -372,6 +372,12 @@ def CC_X86_64_AnyReg : CallingConv<[
   CCCustom<"CC_X86_AnyReg_Error">
 ]>;
 
+def CC_X86_64_Mono : CallingConv<[
+  CCIfInReg<CCAssignToReg<[R10]>>,
+
+  CCDelegateTo<CC_X86_64_C>
+]>;
+
 //===----------------------------------------------------------------------===//
 // X86 C Calling Convention
 //===----------------------------------------------------------------------===//
@@ -543,6 +549,14 @@ def CC_Intel_OCL_BI : CallingConv<[
   CCDelegateTo<CC_X86_32_C>
 ]>;
 
+def CC_X86_32_Mono : CallingConv<[
+  // Mono marks the parameter it wants to pass in this non-abi register with
+  // the 'inreg' attribute.
+  CCIfInReg<CCAssignToReg<[EDX]>>,
+
+  CCDelegateTo<CC_X86_32_C>
+]>;
+
 //===----------------------------------------------------------------------===//
 // X86 Root Argument Calling Conventions
 //===----------------------------------------------------------------------===//
@@ -554,6 +568,7 @@ def CC_X86_32 : CallingConv<[
   CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_X86_32_FastCC>>,
   CCIfCC<"CallingConv::GHC", CCDelegateTo<CC_X86_32_GHC>>,
   CCIfCC<"CallingConv::HiPE", CCDelegateTo<CC_X86_32_HiPE>>,
+  CCIfCC<"CallingConv::Mono", CCDelegateTo<CC_X86_32_Mono>>,
 
   // Otherwise, drop to normal X86-32 CC
   CCDelegateTo<CC_X86_32_C>
@@ -567,6 +582,7 @@ def CC_X86_64 : CallingConv<[
   CCIfCC<"CallingConv::AnyReg", CCDelegateTo<CC_X86_64_AnyReg>>,
   CCIfCC<"CallingConv::X86_64_Win64", CCDelegateTo<CC_X86_Win64_C>>,
   CCIfCC<"CallingConv::X86_64_SysV", CCDelegateTo<CC_X86_64_C>>,
+  CCIfCC<"CallingConv::Mono", CCDelegateTo<CC_X86_64_Mono>>,
 
   // Mingw64 and native Win64 use Win64 CC
   CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_C>>,

   Commit: e0eee3a58fcb9d6bad60282e756093aad0c77a87
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:15:53 GMT
      URL: https://github.com/mono/llvm/commit/e0eee3a58fcb9d6bad60282e756093aad0c77a87

Allow intrinsics which throw exceptions. Allow them to be called using invoke.
Add mono.load/mono.store intrinsics which are the same as load/store, and
lowered to the same code, but can throw exceptions. This enables support for
load/store operations which throw implicit exceptions.

Changed paths:
  M include/llvm/IR/Intrinsics.td
  M lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  M lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
  M lib/IR/Verifier.cpp
Added paths:
  A include/llvm/IR/IntrinsicsMono.td

Modified: include/llvm/IR/Intrinsics.td
===================================================================
@@ -524,3 +524,5 @@ include "llvm/IR/IntrinsicsHexagon.td"
 include "llvm/IR/IntrinsicsNVVM.td"
 include "llvm/IR/IntrinsicsMips.td"
 include "llvm/IR/IntrinsicsR600.td"
+
+include "llvm/IR/IntrinsicsMono.td"

Added: include/llvm/IR/IntrinsicsMono.td
===================================================================
@@ -0,0 +1,25 @@
+//===- IntrinsicsMono.td - Mono specific LLVM intrinsics ---------*- tablegen -*-===//
+
+//
+// Same as the load instruction, but can throw an exception, has to be called using
+// invoke
+// mono.load (addr, align, is_volatile)
+// mono.store (value, addr, align, is_volatile)
+//
+def int_mono_load : Intrinsic<[llvm_anyint_ty],
+                              [LLVMAnyPointerType<LLVMMatchType<0>>,
+							   llvm_i32_ty, llvm_i1_ty],
+                              [IntrReadArgMem, Throws, NoCapture<0>]>;
+
+def int_mono_store : Intrinsic<[],
+                              [llvm_anyint_ty,
+                               LLVMAnyPointerType<LLVMMatchType<0>>,
+							   llvm_i32_ty, llvm_i1_ty],
+                              [IntrReadWriteArgMem, Throws]>;
+
+//
+// Same as sdiv, but can throw an exception
+//
+def int_mono_sdiv : Intrinsic<[llvm_anyint_ty],
+                             [llvm_anyint_ty, llvm_anyint_ty],
+                             [Throws]>;

Modified: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
@@ -1941,6 +1941,50 @@ void SelectionDAGBuilder::visitBitTestCase(BitTestBlock &BB,
   DAG.setRoot(BrAnd);
 }
 
+void SelectionDAGBuilder::LowerIntrinsicTo(ImmutableCallSite CS, unsigned Intrinsic,
+                                           MachineBasicBlock *LandingPad)
+{
+  MCSymbol *BeginLabel = 0;
+
+  if (LandingPad)
+    BeginLabel = EmitTryRangeStart(LandingPad);
+
+  // FIXME: Should merge with visitIntrinsicCall
+  switch (Intrinsic) {
+  default:
+    assert(0);
+  case Intrinsic::mono_load: {
+    const Value *SV = CS.getArgument(0);
+
+    Type *Ty = CS.getType();
+
+    unsigned Alignment = cast<ConstantInt>(CS.getArgument(1))->getZExtValue();
+    bool isVolatile = cast<ConstantInt>(CS.getArgument(2))->getZExtValue();
+    bool isNonTemporal = false;
+    bool isInvariant = false;
+
+    const MDNode *TBAAInfo = NULL;
+
+    handleLoad(*CS.getInstruction(), SV, Ty, isVolatile, isNonTemporal, isInvariant, Alignment, TBAAInfo);
+    break;
+  }
+  case Intrinsic::mono_store: {
+    const Value *SrcV = CS.getArgument(0);
+    const Value *PtrV = CS.getArgument(1);
+    unsigned Alignment = cast<ConstantInt>(CS.getArgument(2))->getZExtValue();
+    bool isVolatile = cast<ConstantInt>(CS.getArgument(3))->getZExtValue();
+    bool isNonTemporal = false;
+    const MDNode *TBAAInfo = NULL;
+
+    handleStore(SrcV, PtrV, isVolatile, isNonTemporal, Alignment, TBAAInfo);
+    break;
+  }
+  }
+
+  if (LandingPad)
+    EmitTryRangeEnd(LandingPad, BeginLabel);
+}
+
 void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
   MachineBasicBlock *InvokeMBB = FuncInfo.MBB;
 
@@ -1953,8 +1997,22 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
   if (isa<InlineAsm>(Callee))
     visitInlineAsm(&I);
   else if (Fn && Fn->isIntrinsic()) {
+    // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+    if (Fn->getIntrinsicID() != Intrinsic::donothing) {
+      unsigned IID = Fn->getIntrinsicID();
+      if (IID)
+        LowerIntrinsicTo (&I, IID, LandingPad);
+    } else {
     assert(Fn->getIntrinsicID() == Intrinsic::donothing);
     // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+    // If donothing has a landingpad, we should clear CurrentCallSite.
+    if (LandingPad) {
+      MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+      unsigned CallSiteIndex = MMI.getCurrentCallSite();
+      if (CallSiteIndex)
+        MMI.setCurrentCallSite(0);
+    }
+}
   } else
     LowerCallTo(&I, getValue(Callee), false, LandingPad);
 
@@ -3363,7 +3421,6 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
     return visitAtomicLoad(I);
 
   const Value *SV = I.getOperand(0);
-  SDValue Ptr = getValue(SV);
 
   Type *Ty = I.getType();
 
@@ -3372,8 +3429,14 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
   bool isInvariant = I.getMetadata("invariant.load") != 0;
   unsigned Alignment = I.getAlignment();
   const MDNode *TBAAInfo = I.getMetadata(LLVMContext::MD_tbaa);
-  const MDNode *Ranges = I.getMetadata(LLVMContext::MD_range);
 
+  handleLoad (I, SV, Ty, isVolatile, isNonTemporal, isInvariant, Alignment, TBAAInfo);
+}
+
+void SelectionDAGBuilder::handleLoad(const Instruction &I, const Value *SV, Type *Ty,
+                                     bool isVolatile, bool isNonTemporal,
+                                     bool isInvariant, unsigned Alignment,
+                                     const MDNode *TBAAInfo) {
   SmallVector<EVT, 4> ValueVTs;
   SmallVector<uint64_t, 4> Offsets;
   ComputeValueVTs(*TM.getTargetLowering(), Ty, ValueVTs, &Offsets);
@@ -3381,9 +3444,11 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
   if (NumValues == 0)
     return;
 
+  SDValue Ptr = getValue(SV);
+
   SDValue Root;
   bool ConstantMemory = false;
-  if (I.isVolatile() || NumValues > MaxParallelChains)
+  if (isVolatile || NumValues > MaxParallelChains)
     // Serialize volatile loads with other side effects.
     Root = getRoot();
   else if (AA->pointsToConstantMemory(
@@ -3420,8 +3485,7 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
                             DAG.getConstant(Offsets[i], PtrVT));
     SDValue L = DAG.getLoad(ValueVTs[i], getCurSDLoc(), Root,
                             A, MachinePointerInfo(SV, Offsets[i]), isVolatile,
-                            isNonTemporal, isInvariant, Alignment, TBAAInfo,
-                            Ranges);
+                            isNonTemporal, isInvariant, Alignment, TBAAInfo);
 
     Values[i] = L;
     Chains[ChainI] = L.getValue(1);
@@ -3448,6 +3512,18 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) {
   const Value *SrcV = I.getOperand(0);
   const Value *PtrV = I.getOperand(1);
 
+  bool isVolatile = I.isVolatile();
+  bool isNonTemporal = I.getMetadata("nontemporal") != 0;
+  unsigned Alignment = I.getAlignment();
+  const MDNode *TBAAInfo = I.getMetadata(LLVMContext::MD_tbaa);
+
+  handleStore (SrcV, PtrV, isVolatile, isNonTemporal, Alignment, TBAAInfo);
+}
+
+void SelectionDAGBuilder::handleStore(const Value *SrcV, const Value *PtrV,
+                                      bool isVolatile, bool isNonTemporal,
+                                      unsigned Alignment, const MDNode *TBAAInfo)
+{
   SmallVector<EVT, 4> ValueVTs;
   SmallVector<uint64_t, 4> Offsets;
   ComputeValueVTs(*TM.getTargetLowering(), SrcV->getType(), ValueVTs, &Offsets);
@@ -3465,10 +3541,6 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) {
   SmallVector<SDValue, 4> Chains(std::min(unsigned(MaxParallelChains),
                                           NumValues));
   EVT PtrVT = Ptr.getValueType();
-  bool isVolatile = I.isVolatile();
-  bool isNonTemporal = I.getMetadata("nontemporal") != 0;
-  unsigned Alignment = I.getAlignment();
-  const MDNode *TBAAInfo = I.getMetadata(LLVMContext::MD_tbaa);
 
   unsigned ChainI = 0;
   for (unsigned i = 0; i != NumValues; ++i, ++ChainI) {
@@ -5319,16 +5391,61 @@ static unsigned getTruncatedArgReg(const SDValue &N) {
     visitPatchpoint(I);
     return 0;
   }
+  case Intrinsic::mono_load:
+  case Intrinsic::mono_store:
+    LowerIntrinsicTo(&I, Intrinsic);
+    return 0;
   }
 }
 
+MCSymbol*
+SelectionDAGBuilder::EmitTryRangeStart(MachineBasicBlock *LandingPad)
+{
+  MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+
+  // Insert a label before the invoke call to mark the try range.  This can be
+  // used to detect deletion of the invoke via the MachineModuleInfo.
+  MCSymbol *BeginLabel = MMI.getContext().CreateTempSymbol();
+
+  // For SjLj, keep track of which landing pads go with which invokes
+  // so as to maintain the ordering of pads in the LSDA.
+  unsigned CallSiteIndex = MMI.getCurrentCallSite();
+  if (CallSiteIndex) {
+    MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
+    LPadToCallSiteMap[LandingPad].push_back(CallSiteIndex);
+
+    // Now that the call site is handled, stop tracking it.
+    MMI.setCurrentCallSite(0);
+  }
+
+  // Both PendingLoads and PendingExports must be flushed here;
+  // this call might not return.
+  (void)getRoot();
+  DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getControlRoot(), BeginLabel));
+
+  return BeginLabel;
+}
+
+void
+SelectionDAGBuilder::EmitTryRangeEnd(MachineBasicBlock *LandingPad, MCSymbol *BeginLabel)
+{
+  MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+
+  // Insert a label at the end of the invoke call to mark the try range.  This
+  // can be used to detect deletion of the invoke via the MachineModuleInfo.
+  MCSymbol *EndLabel = MMI.getContext().CreateTempSymbol();
+  DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getRoot(), EndLabel));
+
+  // Inform MachineModuleInfo of range.
+  MMI.addInvoke(LandingPad, BeginLabel, EndLabel);
+}
+
 void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
                                       bool isTailCall,
                                       MachineBasicBlock *LandingPad) {
   PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
   FunctionType *FTy = cast<FunctionType>(PT->getElementType());
   Type *RetTy = FTy->getReturnType();
-  MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
   MCSymbol *BeginLabel = 0;
 
   TargetLowering::ArgListTy Args;
@@ -5388,27 +5505,8 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
     Args.push_back(Entry);
   }
 
-  if (LandingPad) {
-    // Insert a label before the invoke call to mark the try range.  This can be
-    // used to detect deletion of the invoke via the MachineModuleInfo.
-    BeginLabel = MMI.getContext().CreateTempSymbol();
-
-    // For SjLj, keep track of which landing pads go with which invokes
-    // so as to maintain the ordering of pads in the LSDA.
-    unsigned CallSiteIndex = MMI.getCurrentCallSite();
-    if (CallSiteIndex) {
-      MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
-      LPadToCallSiteMap[LandingPad].push_back(CallSiteIndex);
-
-      // Now that the call site is handled, stop tracking it.
-      MMI.setCurrentCallSite(0);
-    }
-
-    // Both PendingLoads and PendingExports must be flushed here;
-    // this call might not return.
-    (void)getRoot();
-    DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getControlRoot(), BeginLabel));
-  }
+  if (LandingPad)
+    BeginLabel = EmitTryRangeStart(LandingPad);
 
   // Check if target-independent constraints permit a tail call here.
   // Target-dependent constraints are checked within TLI->LowerCallTo.
@@ -5477,15 +5575,8 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
     DAG.setRoot(Result.second);
   }
 
-  if (LandingPad) {
-    // Insert a label at the end of the invoke call to mark the try range.  This
-    // can be used to detect deletion of the invoke via the MachineModuleInfo.
-    MCSymbol *EndLabel = MMI.getContext().CreateTempSymbol();
-    DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getRoot(), EndLabel));
-
-    // Inform MachineModuleInfo of range.
-    MMI.addInvoke(LandingPad, BeginLabel, EndLabel);
-  }
+  if (LandingPad)
+    EmitTryRangeEnd (LandingPad, BeginLabel);
 }
 
 /// IsOnlyUsedInZeroEqualityComparison - Return true if it only matters that the

Modified: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
===================================================================
@@ -618,6 +618,10 @@ class SelectionDAGBuilder {
   void ExportFromCurrentBlock(const Value *V);
   void LowerCallTo(ImmutableCallSite CS, SDValue Callee, bool IsTailCall,
                    MachineBasicBlock *LandingPad = NULL);
+  void LowerIntrinsicTo(ImmutableCallSite CS, unsigned Intrinsic,
+						MachineBasicBlock *LandingPad = NULL);
+  MCSymbol *EmitTryRangeStart(MachineBasicBlock *LandingPad);
+  void EmitTryRangeEnd(MachineBasicBlock *LandingPad, MCSymbol *BeginLabel);
 
   std::pair<SDValue, SDValue> LowerCallOperands(const CallInst &CI,
                                                 unsigned ArgIdx,
@@ -663,6 +667,15 @@ class SelectionDAGBuilder {
                          const MachineBasicBlock *Dst) const;
   void addSuccessorWithWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst,
                               uint32_t Weight = 0);
+
+  void handleLoad(const Instruction &I, const Value *SV, Type *Ty,
+				  bool isVolatile, bool isNonTemporal, bool isInvariant,
+				  unsigned Alignment, const MDNode *TBAAInfo);
+
+  void handleStore(const Value *SrcV, const Value *PtrV,
+				   bool isVolatile, bool isNonTemporal,
+				   unsigned Alignment, const MDNode *TBAAInfo);
+
 public:
   void visitSwitchCase(CaseBlock &CB,
                        MachineBasicBlock *SwitchBB);

Modified: lib/IR/Verifier.cpp
===================================================================
@@ -2045,11 +2045,13 @@ void Verifier::visitInstruction(Instruction &I) {
     if (Function *F = dyn_cast<Function>(I.getOperand(i))) {
       // Check to make sure that the "address of" an intrinsic function is never
       // taken.
+      /*
       Assert1(!F->isIntrinsic() || i == (isa<CallInst>(I) ? e-1 : 0),
               "Cannot take the address of an intrinsic!", &I);
       Assert1(!F->isIntrinsic() || isa<CallInst>(I) ||
               F->getIntrinsicID() == Intrinsic::donothing,
               "Cannot invoke an intrinsinc other than donothing", &I);
+      */
       Assert1(F->getParent() == Mod, "Referencing function in another module!",
               &I);
     } else if (BasicBlock *OpBB = dyn_cast<BasicBlock>(I.getOperand(i))) {

   Commit: a6420a6d1472ceb11326b66b3b2a39b094cdb2a2
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:16:03 GMT
      URL: https://github.com/mono/llvm/commit/a6420a6d1472ceb11326b66b3b2a39b094cdb2a2

Add support for passing blockaddress-es as normal parameters in calls.

Changed paths:
  M lib/Target/X86/X86CodeEmitter.cpp
  M lib/Transforms/Utils/CloneFunction.cpp

Modified: lib/Target/X86/X86CodeEmitter.cpp
===================================================================
@@ -87,6 +87,9 @@
     void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
                            intptr_t Disp = 0, intptr_t PCAdj = 0,
                            bool Indirect = false);
+	void emitBlockAddress(const MachineInstr& MI,
+						  const MachineOperand &MO,
+						  unsigned Reloc);
     void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
     void emitConstPoolAddress(unsigned CPI, unsigned Reloc, intptr_t Disp = 0,
                               intptr_t PCAdj = 0);
@@ -294,6 +297,35 @@ static unsigned determineREX(const MachineInstr &MI) {
     MCE.emitWordLE((int32_t)Disp);
 }
 
+/// emitBlockAddress - Emit the address of a basic block to the code stream
+///
+template<class CodeEmitter>
+void Emitter<CodeEmitter>::emitBlockAddress(const MachineInstr& MI,
+											const MachineOperand &MO,
+											unsigned Reloc)
+{
+	// Ugly, but the BlockAddress refers to the original LLVM bblock
+	const MachineFunction *MF = MI.getParent()->getParent();
+	const MachineBasicBlock *TargetBB = NULL;
+	for (MachineFunction::const_iterator MBB2 = MF->begin(), E = MF->end();
+		 MBB2 != E; ++MBB2) {
+        if (MBB2->getBasicBlock() == MO.getBlockAddress()->getBasicBlock()) {
+			TargetBB = MBB2;
+			break;
+        }
+	}
+	assert(TargetBB);
+	MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
+											   Reloc,
+											   const_cast<MachineBasicBlock*>(TargetBB)));
+	if (Reloc == X86::reloc_absolute_word)
+        MCE.emitWordLE(0);
+	else if (Reloc == X86::reloc_absolute_dword)
+        MCE.emitDWordLE(0);
+	else
+        assert(0);
+}
+
 /// emitExternalSymbolAddress - Arrange for the address of an external symbol to
 /// be emitted to the current location in the function, and allow it to be PC
 /// relative.
@@ -1280,6 +1312,8 @@ static bool Is64BitMemOperand(const MachineInstr &MI, unsigned Op) {
       bool Indirect = gvNeedsNonLazyPtr(MO1, TM);
       emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
                         Indirect);
+    } else if (MO1.isBlockAddress()) {
+		emitBlockAddress(MI, MO1, rt);
     } else if (MO1.isSymbol())
       emitExternalSymbolAddress(MO1.getSymbolName(), rt);
     else if (MO1.isCPI())
@@ -1423,6 +1457,8 @@ static bool Is64BitMemOperand(const MachineInstr &MI, unsigned Op) {
       bool Indirect = gvNeedsNonLazyPtr(MO, TM);
       emitGlobalAddress(MO.getGlobal(), rt, MO.getOffset(), 0,
                         Indirect);
+    } else if (MO.isBlockAddress()) {
+		emitBlockAddress(MI, MO, rt);
     } else if (MO.isSymbol())
       emitExternalSymbolAddress(MO.getSymbolName(), rt);
     else if (MO.isCPI())

Modified: lib/Transforms/Utils/CloneFunction.cpp
===================================================================
@@ -378,6 +378,9 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
     assert(VMap.count(II) && "No mapping from source argument specified!");
 #endif
 
+  // BlockAddress remapping requires this
+  VMap[OldFunc] = NewFunc;
+
   PruningFunctionCloner PFC(NewFunc, OldFunc, VMap, ModuleLevelChanges,
                             NameSuffix, CodeInfo, TD);
 

   Commit: b855c4e6203ada4e2e57e52b5f26e76697f724c3
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:16:12 GMT
      URL: https://github.com/mono/llvm/commit/b855c4e6203ada4e2e57e52b5f26e76697f724c3

Add a workaround to the problem where the amd64 JIT would make all calls as register indirect.

Changed paths:
  M lib/Target/X86/X86ISelLowering.cpp

Modified: lib/Target/X86/X86ISelLowering.cpp
===================================================================
@@ -2763,6 +2763,17 @@ static bool FuncIsMadeTailCallSafe(CallingConv::ID CC,
     // through a register, since the call instruction's 32-bit
     // pc-relative offset may not be large enough to hold the whole
     // address.
+
+    //
+    // This is a mono specific hack to force llvm to generate direct calls even if
+    // the code model is Large.
+    //
+    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
+      unsigned char OpFlags = 0;
+      const GlobalValue *GV = G->getGlobal();
+      Callee = DAG.getTargetGlobalAddress(GV, dl, getPointerTy(),
+                                          G->getOffset(), OpFlags);
+    }
   } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
     // If the callee is a GlobalAddress node (quite common, every direct call
     // is) turn it into a TargetGlobalAddress node so that legalize doesn't hack

   Commit: 922e447f718578bafa8173520c6f0b3c7f42630a
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:16:21 GMT
      URL: https://github.com/mono/llvm/commit/922e447f718578bafa8173520c6f0b3c7f42630a

Add a -mono suffix and the git revision to the output of llvm-config --version.

Changed paths:
  M tools/llvm-config/BuildVariables.inc.in
  M tools/llvm-config/Makefile
  M tools/llvm-config/llvm-config.cpp

Modified: tools/llvm-config/BuildVariables.inc.in
===================================================================
@@ -25,3 +25,4 @@
 #define LLVM_BUILDMODE "@LLVM_BUILDMODE@"
 #define LLVM_TARGETS_BUILT "@LLVM_TARGETS_BUILT@"
 #define LLVM_SYSTEM_LIBS "@LLVM_SYSTEM_LIBS@"
+#define LLVM_GIT_VERSION "@LLVM_GIT_VERSION@"

Modified: tools/llvm-config/Makefile
===================================================================
@@ -55,8 +55,12 @@ $(ObjDir)/BuildVariables.inc: $(BUILDVARIABLES_SRCPATH) Makefile $(ObjDir)/.dir
 	  >> temp.sed
 	$(Verb) $(ECHO) 's/@LLVM_TARGETS_BUILT@/$(subst /,\/,$(TARGETS_TO_BUILD))/' \
 	  >> temp.sed
+	$(Verb) branch=`git branch | grep '^\*' | cut -d ' ' -f 2`; \
+	version=`git log --no-color --first-parent -n1 --pretty=format:%h`; \
+	git_version="$$branch/$$version"; \
+	$(ECHO) "s,@LLVM_GIT_VERSION@,$$git_version," \
+	  >> temp.sed
 	$(Verb) $(SED) -f temp.sed < $< > $@
-	$(Verb) $(RM) temp.sed
 
 # When cross-compiling, install a version of llvm-config that runs on the host.
 ifeq ($(LLVM_CROSS_COMPILING),1)

Modified: tools/llvm-config/llvm-config.cpp
===================================================================
@@ -261,7 +261,7 @@ int main(int argc, char **argv) {
     if (Arg.startswith("-")) {
       HasAnyOption = true;
       if (Arg == "--version") {
-        OS << PACKAGE_VERSION << '\n';
+        OS << PACKAGE_VERSION << "-mono-" << LLVM_GIT_VERSION << '\n';
       } else if (Arg == "--prefix") {
         OS << ActivePrefix << '\n';
       } else if (Arg == "--bindir") {

   Commit: b768025e0ae0a8c93e6dfd8800fea1f2af012b51
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:16:30 GMT
      URL: https://github.com/mono/llvm/commit/b768025e0ae0a8c93e6dfd8800fea1f2af012b51

Fix some conflicts between command line arguments and the arguments used to control passes, sometimes they are the same, which causes problems if both the optimization and the code generation passes are linked into the same executable.

Changed paths:
  M lib/CodeGen/MachineFunctionPrinterPass.cpp
  M lib/CodeGen/MachineScheduler.cpp

Modified: lib/CodeGen/MachineFunctionPrinterPass.cpp
===================================================================
@@ -52,7 +52,7 @@ struct MachineFunctionPrinterPass : public MachineFunctionPass {
 }
 
 char &llvm::MachineFunctionPrinterPassID = MachineFunctionPrinterPass::ID;
-INITIALIZE_PASS(MachineFunctionPrinterPass, "print-machineinstrs",
+INITIALIZE_PASS(MachineFunctionPrinterPass, "print-machineinstrs-2",
                 "Machine Function Printer", false, false)
 
 namespace llvm {

Modified: lib/CodeGen/MachineScheduler.cpp
===================================================================
@@ -111,12 +111,12 @@ class MachineScheduler : public MachineSchedContext,
 
 char &llvm::MachineSchedulerID = MachineScheduler::ID;
 
-INITIALIZE_PASS_BEGIN(MachineScheduler, "misched",
+INITIALIZE_PASS_BEGIN(MachineScheduler, "misched-2",
                       "Machine Instruction Scheduler", false, false)
 INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
-INITIALIZE_PASS_END(MachineScheduler, "misched",
+INITIALIZE_PASS_END(MachineScheduler, "misched-2",
                     "Machine Instruction Scheduler", false, false)
 
 MachineScheduler::MachineScheduler()

   Commit: d887d47252319a4308f14b11625d3fe25b45869c
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:24:49 GMT
      URL: https://github.com/mono/llvm/commit/d887d47252319a4308f14b11625d3fe25b45869c

Add support for Mono EH to the JIT and the static compiler. For the JIT, emit a variant of the C++ EH structures which contains extra information required by mono, i.e. the stack location of 'this'. For the static compiler, emit separate tables instead of the normal C++ tables. Add back parts of the LLVM JIT EH support code removed in r181354 and r181649.

Changed paths:
  M include/llvm/CodeGen/MachineFunction.h
  M include/llvm/ExecutionEngine/ExecutionEngine.h
  M include/llvm/ExecutionEngine/JITMemoryManager.h
  M include/llvm/MC/MCObjectFileInfo.h
  M include/llvm/Target/TargetOptions.h
  M lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  M lib/CodeGen/AsmPrinter/DwarfException.cpp
  M lib/CodeGen/AsmPrinter/DwarfException.h
  M lib/CodeGen/MachineFunction.cpp
  M lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
  M lib/ExecutionEngine/ExecutionEngine.cpp
  M lib/ExecutionEngine/JIT/CMakeLists.txt
  M lib/ExecutionEngine/JIT/JIT.cpp
  M lib/ExecutionEngine/JIT/JITEmitter.cpp
  M lib/ExecutionEngine/JIT/JITMemoryManager.cpp
  M lib/MC/MCObjectFileInfo.cpp
  M lib/Transforms/Scalar/GlobalMerge.cpp
  M tools/lli/RemoteMemoryManager.h
  M unittests/ExecutionEngine/JIT/JITTest.cpp
Added paths:
  A include/llvm/CodeGen/MonoMachineFunctionInfo.h
  A lib/CodeGen/AsmPrinter/DwarfMonoException.cpp
  A lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
  A lib/ExecutionEngine/JIT/JITDwarfEmitter.h

Modified: include/llvm/CodeGen/MachineFunction.h
===================================================================
@@ -40,6 +40,7 @@
 class TargetMachine;
 class TargetRegisterClass;
 struct MachinePointerInfo;
+class MonoMachineFunctionInfo;
 
 template <>
 struct ilist_traits<MachineBasicBlock>
@@ -134,6 +135,8 @@ class MachineFunction {
   /// True if the function includes MS-style inline assembly.
   bool HasMSInlineAsm;
 
+  MonoMachineFunctionInfo *MonoInfo;
+
   MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION;
   void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION;
 public:
@@ -192,6 +195,9 @@ class MachineFunction {
   MachineConstantPool *getConstantPool() { return ConstantPool; }
   const MachineConstantPool *getConstantPool() const { return ConstantPool; }
 
+  MonoMachineFunctionInfo *getMonoInfo() { return MonoInfo; }
+  const MonoMachineFunctionInfo *getMonoInfo() const { return MonoInfo; }
+
   /// getAlignment - Return the alignment (log2, not bytes) of the function.
   ///
   unsigned getAlignment() const { return Alignment; }

Added: include/llvm/CodeGen/MonoMachineFunctionInfo.h
===================================================================
@@ -0,0 +1,33 @@
+#ifndef LLVM_CODEGEN_MACHINMONOEFUNCTION_H
+#define LLVM_CODEGEN_MACHINMONOEFUNCTION_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class MonoMachineFunctionInfo {
+
+  int ThisStackSlot;
+
+ public:
+
+  MonoMachineFunctionInfo(MachineFunction &MF) : ThisStackSlot (-1) {
+  }
+
+  virtual ~MonoMachineFunctionInfo () {
+  }
+
+  void setThisStackSlot (int slot) {
+	  ThisStackSlot = slot;
+  }
+
+  int getThisStackSlot () const {
+	  return ThisStackSlot;
+  }
+};
+
+}
+
+#endif

Modified: include/llvm/ExecutionEngine/ExecutionEngine.h
===================================================================
@@ -16,6 +16,7 @@
 #define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
 
 #include "llvm-c/ExecutionEngine.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/ValueMap.h"
@@ -152,6 +153,14 @@ class ExecutionEngine {
   /// abort.
   void *(*LazyFunctionCreator)(const std::string &);
 
+  /// ExceptionTableRegister - If Exception Handling is set, the JIT will
+  /// register dwarf tables with this function.
+  typedef void (*EERegisterFn)(void*);
+  EERegisterFn ExceptionTableRegister;
+  EERegisterFn ExceptionTableDeregister;
+  /// This maps functions to their exception tables frames.
+  DenseMap<const Function*, void*> AllExceptionTables;
+
 public:
   /// lock - This lock protects the ExecutionEngine, MCJIT, JIT, JITResolver and
   /// JITEmitter classes.  It must be held while changing the internal state of
@@ -482,6 +491,41 @@ class ExecutionEngine {
     LazyFunctionCreator = P;
   }
 
+  /// InstallExceptionTableRegister - The JIT will use the given function
+  /// to register the exception tables it generates.
+  void InstallExceptionTableRegister(EERegisterFn F) {
+    ExceptionTableRegister = F;
+  }
+  void InstallExceptionTableDeregister(EERegisterFn F) {
+    ExceptionTableDeregister = F;
+  }
+
+  /// RegisterTable - Registers the given pointer as an exception table.  It
+  /// uses the ExceptionTableRegister function.
+  void RegisterTable(const Function *fn, void* res) {
+    if (ExceptionTableRegister) {
+      ExceptionTableRegister(res);
+      AllExceptionTables[fn] = res;
+    }
+  }
+
+  /// DeregisterTable - Deregisters the exception frame previously registered
+  /// for the given function.
+  void DeregisterTable(const Function *Fn) {
+    if (ExceptionTableDeregister) {
+      DenseMap<const Function*, void*>::iterator frame =
+        AllExceptionTables.find(Fn);
+      if(frame != AllExceptionTables.end()) {
+        ExceptionTableDeregister(frame->second);
+        AllExceptionTables.erase(frame);
+      }
+    }
+  }
+
+  /// DeregisterAllTables - Deregisters all previously registered pointers to an
+  /// exception tables.  It uses the ExceptionTableoDeregister function.
+  void DeregisterAllTables();
+
 protected:
   explicit ExecutionEngine(Module *M);
 

Modified: include/llvm/ExecutionEngine/JITMemoryManager.h
===================================================================
@@ -115,6 +115,22 @@ class JITMemoryManager : public RTDyldMemoryManager {
   /// emitting a function.
   virtual void deallocateFunctionBody(void *Body) = 0;
 
+  /// startExceptionTable - When we finished JITing the function, if exception
+  /// handling is set, we emit the exception table.
+  virtual uint8_t* startExceptionTable(const Function* F,
+                                       uintptr_t &ActualSize) = 0;
+
+  /// endExceptionTable - This method is called when the JIT is done emitting
+  /// the exception table.
+  virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
+                                 uint8_t *TableEnd, uint8_t* FrameRegister) = 0;
+
+  /// deallocateExceptionTable - Free the specified exception table's memory.
+  /// The argument must be the return value from a call to startExceptionTable()
+  /// that hasn't been deallocated yet.  This is never called when the JIT is
+  /// currently emitting an exception table.
+  virtual void deallocateExceptionTable(void *ET) = 0;
+
   /// CheckInvariants - For testing only.  Return true if all internal
   /// invariants are preserved, or return false and set ErrorStr to a helpful
   /// error message.

Modified: include/llvm/MC/MCObjectFileInfo.h
===================================================================
@@ -50,6 +50,7 @@ class MCObjectFileInfo {
   /// Section flags for eh_frame
   unsigned EHSectionType;
   unsigned EHSectionFlags;
+  unsigned MonoEHTableEncoding;
 
   /// CompactUnwindDwarfEHFrameOnly - Compact unwind encoding indicating that we
   /// should emit only an EH frame.
@@ -211,6 +212,7 @@ class MCObjectFileInfo {
     return CFI ? FDECFIEncoding : FDEEncoding;
   }
   unsigned getTTypeEncoding() const { return TTypeEncoding; }
+  unsigned getMonoEHTableEncoding() const { return MonoEHTableEncoding; }
 
   unsigned getCompactUnwindDwarfEHFrameOnly() const {
     return CompactUnwindDwarfEHFrameOnly;

Modified: include/llvm/Target/TargetOptions.h
===================================================================
@@ -45,7 +45,7 @@
           LessPreciseFPMADOption(false),
           UnsafeFPMath(false), NoInfsFPMath(false),
           NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false),
-          UseSoftFloat(false), NoZerosInBSS(false),
+          UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(false),
           JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false),
           GuaranteedTailCallOpt(false), DisableTailCalls(false),
           StackAlignmentOverride(0),
@@ -117,6 +117,10 @@
     /// crt*.o compiling).
     unsigned NoZerosInBSS : 1;
 
+    /// JITExceptionHandling - This flag indicates that the JIT should emit
+    /// exception handling information.
+    unsigned JITExceptionHandling : 1;
+
     /// JITEmitDebugInfo - This flag indicates that the JIT should try to emit
     /// debug information and notify a debugger about it.
     unsigned JITEmitDebugInfo : 1;
@@ -204,6 +208,7 @@
     ARE_EQUAL(HonorSignDependentRoundingFPMathOption) &&
     ARE_EQUAL(UseSoftFloat) &&
     ARE_EQUAL(NoZerosInBSS) &&
+    ARE_EQUAL(JITExceptionHandling) &&
     ARE_EQUAL(JITEmitDebugInfo) &&
     ARE_EQUAL(JITEmitDebugInfoToDisk) &&
     ARE_EQUAL(GuaranteedTailCallOpt) &&

Modified: lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
@@ -37,6 +37,7 @@
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/MathExtras.h"
@@ -57,6 +58,9 @@
 
 STATISTIC(EmittedInsts, "Number of machine instrs printed");
 
+cl::opt<bool> EnableMonoEH("enable-mono-eh-frame", cl::NotHidden,
+     cl::desc("Enable generation of Mono specific EH tables"));
+
 char AsmPrinter::ID = 0;
 
 typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type;
@@ -195,6 +199,11 @@ bool AsmPrinter::doInitialization(Module &M) {
   if (MAI->doesSupportDebugInformation())
     DD = new DwarfDebug(this, &M);
 
+  if (EnableMonoEH) {
+    DE = new DwarfMonoException(this);
+    return false;
+  }
+
   switch (MAI->getExceptionHandlingType()) {
   case ExceptionHandling::None:
     return false;
@@ -723,7 +732,10 @@ void AsmPrinter::EmitFunctionBody() {
 
       switch (II->getOpcode()) {
       case TargetOpcode::PROLOG_LABEL:
-        emitPrologLabel(*II);
+        if (EnableMonoEH)
+          OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol());
+        else
+          emitPrologLabel(*II);
         break;
 
       case TargetOpcode::EH_LABEL:

Modified: lib/CodeGen/AsmPrinter/DwarfException.cpp
===================================================================
@@ -19,6 +19,8 @@
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MonoMachineFunctionInfo.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Module.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -27,6 +29,7 @@
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FormattedStream.h"

Modified: lib/CodeGen/AsmPrinter/DwarfException.h
===================================================================
@@ -15,6 +15,8 @@
 #define LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/IR/Module.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include <vector>
 
@@ -43,6 +45,17 @@ class DwarfException {
   /// MMI - Collected machine module information.
   MachineModuleInfo *MMI;
 
+  /// CallSiteEntry - Structure describing an entry in the call-site table.
+  struct CallSiteEntry {
+    // The 'try-range' is BeginLabel .. EndLabel.
+    MCSymbol *BeginLabel; // zero indicates the start of the function.
+    MCSymbol *EndLabel;   // zero indicates the end of the function.
+
+    // The landing pad starts at PadLabel.
+    MCSymbol *PadLabel;   // zero indicates that there is no landing pad.
+    unsigned Action;
+  };
+
   /// SharedTypeIds - How many leading type ids two landing pads have in common.
   static unsigned SharedTypeIds(const LandingPadInfo *L,
                                 const LandingPadInfo *R);
@@ -67,17 +80,55 @@ class DwarfException {
     unsigned Previous;
   };
 
-  /// CallSiteEntry - Structure describing an entry in the call-site table.
-  struct CallSiteEntry {
+  struct MonoCallSiteEntry {
     // The 'try-range' is BeginLabel .. EndLabel.
     MCSymbol *BeginLabel; // zero indicates the start of the function.
     MCSymbol *EndLabel;   // zero indicates the end of the function.
 
     // The landing pad starts at PadLabel.
     MCSymbol *PadLabel;   // zero indicates that there is no landing pad.
-    unsigned Action;
+	int TypeID;
+  };
+
+  // Mono specific
+  struct MonoEHFrameInfo {
+    const MachineFunction *MF;
+    std::vector<MonoCallSiteEntry> CallSites;
+    std::vector<const GlobalVariable *> TypeInfos;
+    std::vector<unsigned> FilterIds;
+    std::vector<LandingPadInfo> PadInfos;
+    int FunctionNumber;
+    int MonoMethodIdx;
+    int FrameReg;
+    int ThisOffset;
   };
 
+  struct FunctionEHFrameInfo {
+    MCSymbol *FunctionEHSym;  // L_foo.eh
+    unsigned Number;
+    unsigned PersonalityIndex;
+    bool adjustsStack;
+    bool hasLandingPads;
+    std::vector<MCCFIInstruction> Instructions;
+    const Function *function;
+
+    MonoEHFrameInfo MonoEH;
+
+    FunctionEHFrameInfo(MCSymbol *EHSym, unsigned Num, unsigned P,
+                        bool hC, bool hL,
+                        const std::vector<MCCFIInstruction> &M,
+                        const Function *f):
+      FunctionEHSym(EHSym), Number(Num), PersonalityIndex(P),
+      adjustsStack(hC), hasLandingPads(hL), Instructions(M), function (f) { }
+  };
+
+  std::vector<FunctionEHFrameInfo> EHFrames;
+
+  /// UsesLSDA - Indicates whether an FDE that uses the CIE at the given index
+  /// uses an LSDA. If so, then we need to encode that information in the CIE's
+  /// augmentation.
+  DenseMap<unsigned, bool> UsesLSDA;
+
   /// ComputeActionsTable - Compute the actions table and gather the first
   /// action index for each landing pad site.
   unsigned ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*>&LPs,
@@ -231,6 +282,36 @@ class Win64Exception : public DwarfException {
   virtual void EndFunction();
 };
 
+class DwarfMonoException : public DwarfException {
+
+  StringMap<int> FuncIndexes;
+
+public:
+  //===--------------------------------------------------------------------===//
+  // Main entry points.
+  //
+  DwarfMonoException(AsmPrinter *A);
+  virtual ~DwarfMonoException();
+
+  /// EndModule - Emit all exception information that should come after the
+  /// content.
+  virtual void EndModule();
+
+  /// BeginFunction - Gather pre-function exception information.  Assumes being
+  /// emitted immediately after the function entry point.
+  virtual void BeginFunction(const MachineFunction *MF);
+
+  /// EndFunction - Gather and emit post-function exception information.
+  virtual void EndFunction();
+
+  // EmitMonoEHFrame - Emit Mono specific exception handling tables
+  void EmitMonoEHFrame(const Function *Personality);
+
+  void PrepareMonoLSDA(FunctionEHFrameInfo *EHFrameInfo);
+
+  void EmitMonoLSDA(const FunctionEHFrameInfo *EHFrameInfo);
+};
+
 } // End of namespace llvm
 
 #endif

Added: lib/CodeGen/AsmPrinter/DwarfMonoException.cpp
===================================================================
@@ -0,0 +1,686 @@
+//===-- CodeGen/AsmPrinter/DwarfMonoException.cpp - Dwarf Exception Impl ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains code to emit Mono specific exception handling tables.
+// It is based on code in DwarfException.cpp and MCDwarf.cpp.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DwarfException.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MonoMachineFunctionInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Twine.h"
+using namespace llvm;
+
+// FIXME:
+static cl::opt<bool> DisableGNUEH("disable-gnu-eh-frame", cl::NotHidden,
+                                  cl::desc("Disable generation of GNU .eh_frame"));
+
+static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
+                                                  const MCSymbol &Start,
+                                                  const MCSymbol &End,
+                                                  int IntVal) {
+  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+  const MCExpr *Res =
+    MCSymbolRefExpr::Create(&End, Variant, MCOS.getContext());
+  const MCExpr *RHS =
+    MCSymbolRefExpr::Create(&Start, Variant, MCOS.getContext());
+  const MCExpr *Res1 =
+    MCBinaryExpr::Create(MCBinaryExpr::Sub, Res, RHS, MCOS.getContext());
+  const MCExpr *Res2 =
+    MCConstantExpr::Create(IntVal, MCOS.getContext());
+  const MCExpr *Res3 =
+    MCBinaryExpr::Create(MCBinaryExpr::Sub, Res1, Res2, MCOS.getContext());
+  return Res3;
+}
+
+void EmitCFIInstruction(MCStreamer &Streamer,
+                        const MCCFIInstruction &Instr,
+                        int &CFAOffset, int DataAlignmentFactor) {
+  // Same as MCDwarf::EmitCFIInstruction ()
+  // FIXME: Unify
+  int dataAlignmentFactor = DataAlignmentFactor;
+  bool VerboseAsm = Streamer.isVerboseAsm();
+
+  switch (Instr.getOperation()) {
+  case MCCFIInstruction::OpWindowSave: {
+    Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
+    return;
+  }
+  case MCCFIInstruction::OpUndefined: {
+    unsigned Reg = Instr.getRegister();
+    if (VerboseAsm) {
+      Streamer.AddComment("DW_CFA_undefined");
+      Streamer.AddComment(Twine("Reg ") + Twine(Reg));
+    }
+    Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
+    Streamer.EmitULEB128IntValue(Reg);
+    return;
+  }
+  case MCCFIInstruction::OpAdjustCfaOffset:
+  case MCCFIInstruction::OpDefCfaOffset: {
+    const bool IsRelative =
+      Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset;
+
+    if (VerboseAsm)
+      Streamer.AddComment("DW_CFA_def_cfa_offset");
+    Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
+
+    if (IsRelative)
+      CFAOffset += Instr.getOffset();
+    else
+      // The backends pass in a negative value,
+      // then createDefCfaOffset () negates it
+      CFAOffset = Instr.getOffset();
+
+    if (VerboseAsm)
+      Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
+    Streamer.EmitULEB128IntValue(CFAOffset);
+
+    return;
+  }
+  case MCCFIInstruction::OpDefCfa: {
+    if (VerboseAsm)
+      Streamer.AddComment("DW_CFA_def_cfa");
+    Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
+
+    if (VerboseAsm)
+      Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
+    Streamer.EmitULEB128IntValue(Instr.getRegister());
+
+    // createX86MCAsmInfo () passes in a positive value, which is
+    // negated by createDefCfa ()
+    CFAOffset = -Instr.getOffset();
+
+    if (VerboseAsm)
+      Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
+    Streamer.EmitULEB128IntValue(CFAOffset);
+
+    return;
+  }
+
+  case MCCFIInstruction::OpDefCfaRegister: {
+    if (VerboseAsm)
+      Streamer.AddComment("DW_CFA_def_cfa_register");
+    Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
+
+    if (VerboseAsm)
+      Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
+    Streamer.EmitULEB128IntValue(Instr.getRegister());
+
+    return;
+  }
+
+  case MCCFIInstruction::OpOffset:
+  case MCCFIInstruction::OpRelOffset: {
+    const bool IsRelative =
+      Instr.getOperation() == MCCFIInstruction::OpRelOffset;
+
+    unsigned Reg = Instr.getRegister();
+    int Offset = Instr.getOffset();
+    if (IsRelative)
+      Offset -= CFAOffset;
+    Offset = Offset / dataAlignmentFactor;
+
+    if (Offset < 0) {
+      if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended_sf");
+      Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1);
+      if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
+      Streamer.EmitULEB128IntValue(Reg);
+      if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
+      Streamer.EmitSLEB128IntValue(Offset);
+    } else if (Reg < 64) {
+      if (VerboseAsm) Streamer.AddComment(Twine("DW_CFA_offset + Reg(") +
+                                          Twine(Reg) + ")");
+      Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1);
+      if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
+      Streamer.EmitULEB128IntValue(Offset);
+    } else {
+      if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended");
+      Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
+      if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
+      Streamer.EmitULEB128IntValue(Reg);
+      if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
+      Streamer.EmitULEB128IntValue(Offset);
+    }
+    return;
+  }
+  case MCCFIInstruction::OpRememberState:
+    if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state");
+    Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
+    return;
+  case MCCFIInstruction::OpRestoreState:
+    if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state");
+    Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
+    return;
+  case MCCFIInstruction::OpSameValue: {
+    unsigned Reg = Instr.getRegister();
+    if (VerboseAsm) Streamer.AddComment("DW_CFA_same_value");
+    Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1);
+    if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
+    Streamer.EmitULEB128IntValue(Reg);
+    return;
+  }
+  case MCCFIInstruction::OpRestore: {
+    unsigned Reg = Instr.getRegister();
+    if (VerboseAsm) {
+      Streamer.AddComment("DW_CFA_restore");
+      Streamer.AddComment(Twine("Reg ") + Twine(Reg));
+    }
+    Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
+    return;
+  }
+  case MCCFIInstruction::OpEscape:
+    if (VerboseAsm) Streamer.AddComment("Escape bytes");
+    Streamer.EmitBytes(Instr.getValues());
+    return;
+  case MCCFIInstruction::OpRegister:
+	  llvm_unreachable("Unhandled case in switch");	
+	  return;
+  }
+  llvm_unreachable("Unhandled case in switch");
+}
+
+/// EmitFrameMoves - Emit frame instructions to describe the layout of the
+/// frame.
+void EmitCFIInstructions(MCStreamer &streamer,
+                         const std::vector<MCCFIInstruction> &Instrs,
+                         MCSymbol *BaseLabel,
+                         int &CFAOffset,
+                         int DataAlignmentFactor) {
+  for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
+    const MCCFIInstruction &Instr = Instrs[i];
+    MCSymbol *Label = Instr.getLabel();
+    // Throw out move if the label is invalid.
+    //if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
+
+    // Advance row if new location.
+    if (BaseLabel && Label) {
+      MCSymbol *ThisSym = Label;
+      if (ThisSym != BaseLabel) {
+        streamer.AddComment ("cfa_advance");
+        streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
+        BaseLabel = ThisSym;
+      }
+    }
+
+    EmitCFIInstruction(streamer, Instr, CFAOffset, DataAlignmentFactor);
+  }
+}
+
+/// PrepareMonoLSDA - Collect information needed by EmitMonoLSDA
+///
+///   This function collects information available only during EndFunction which is needed
+/// by EmitMonoLSDA and stores it into EHFrameInfo. It is the same as the
+/// beginning of EmitExceptionTable.
+///
+void DwarfMonoException::PrepareMonoLSDA(FunctionEHFrameInfo *EHFrameInfo) {
+  const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
+  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
+  const MachineFunction *MF = Asm->MF;
+
+  // Sort the landing pads in order of their type ids.  This is used to fold
+  // duplicate actions.
+  SmallVector<const LandingPadInfo *, 64> LandingPads;
+  LandingPads.reserve(PadInfos.size());
+
+  for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
+    LandingPads.push_back(&PadInfos[i]);
+
+  std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
+
+#if 0
+  // Compute the actions table and gather the first action index for each
+  // landing pad site.
+  SmallVector<ActionEntry, 32> Actions;
+  SmallVector<unsigned, 64> FirstActions;
+  ComputeActionsTable(LandingPads, Actions, FirstActions);
+#endif
+
+  // Invokes and nounwind calls have entries in PadMap (due to being bracketed
+  // by try-range labels when lowered).  Ordinary calls do not, so appropriate
+  // try-ranges for them need be deduced when using DWARF exception handling.
+  RangeMapType PadMap;
+  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
+    const LandingPadInfo *LandingPad = LandingPads[i];
+    for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
+      MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
+      assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
+      PadRange P = { i, j };
+      PadMap[BeginLabel] = P;
+    }
+  }
+
+  // Compute the call-site table.
+  SmallVector<MonoCallSiteEntry, 64> CallSites;
+  //ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions);
+
+  MCSymbol *LastLabel = 0;
+  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+        I != E; ++I) {
+    for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
+          MI != E; ++MI) {
+      if (!MI->isLabel()) {
+        continue;
+      }
+
+      MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol();
+      assert(BeginLabel && "Invalid label!");
+
+      RangeMapType::iterator L = PadMap.find(BeginLabel);
+
+      if (L == PadMap.end())
+        continue;
+
+      PadRange P = L->second;
+      const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
+
+      assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
+              "Inconsistent landing pad map!");
+
+      // Mono emits one landing pad for each CLR exception clause,
+      // and the type info contains the clause index
+      assert (LandingPad->TypeIds.size() == 1);
+      assert (LandingPad->LandingPadLabel);
+
+      LastLabel = LandingPad->EndLabels[P.RangeIndex];
+      MonoCallSiteEntry Site = {BeginLabel, LastLabel,
+							LandingPad->LandingPadLabel, LandingPad->TypeIds [0]};
+
+      assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
+              "Invalid landing pad!");
+
+      // Try to merge with the previous call-site.
+      if (CallSites.size()) {
+        MonoCallSiteEntry &Prev = CallSites.back();
+        if (Site.PadLabel == Prev.PadLabel && Site.TypeID == Prev.TypeID) {
+          // Extend the range of the previous entry.
+          Prev.EndLabel = Site.EndLabel;
+          continue;
+        }
+      }
+
+      // Otherwise, create a new call-site.
+      CallSites.push_back(Site);
+    }
+  }
+
+  //
+  // Compute a mapping from method names to their AOT method index
+  //
+  if (FuncIndexes.size () == 0) {
+    const Module *m = MMI->getModule ();
+    NamedMDNode *indexes = m->getNamedMetadata ("mono.function_indexes");
+	if (indexes) {
+      for (unsigned int i = 0; i < indexes->getNumOperands (); ++i) {
+        MDNode *n = indexes->getOperand (i);
+        MDString *s = (MDString*)n->getOperand (0);
+        ConstantInt *idx = (ConstantInt*)n->getOperand (1);
+        FuncIndexes.GetOrCreateValue (s->getString (), (int)idx->getLimitedValue () + 1);
+      }
+    }
+  }
+
+  MonoEHFrameInfo *MonoEH = &EHFrameInfo->MonoEH;
+
+  // Save information for EmitMonoLSDA
+  MonoEH->MF = Asm->MF;
+  MonoEH->FunctionNumber = Asm->getFunctionNumber();
+  MonoEH->CallSites.insert(MonoEH->CallSites.begin(), CallSites.begin(), CallSites.end());
+  MonoEH->TypeInfos = TypeInfos;
+  MonoEH->PadInfos = PadInfos;
+  MonoEH->MonoMethodIdx = FuncIndexes.lookup (Asm->MF->getFunction ()->getName ()) - 1;
+  //outs()<<"A:"<<Asm->MF->getFunction()->getName() << " " << MonoEH->MonoMethodIdx << "\n";
+
+  int ThisSlot = Asm->MF->getMonoInfo()->getThisStackSlot();
+
+  if (ThisSlot != -1) {
+    unsigned FrameReg;
+    MonoEH->ThisOffset = Asm->MF->getTarget ().getFrameLowering ()->getFrameIndexReference (*Asm->MF, ThisSlot, FrameReg);
+    MonoEH->FrameReg = Asm->MF->getTarget ().getRegisterInfo ()->getDwarfRegNum (FrameReg, true);
+  } else {
+    MonoEH->FrameReg = -1;
+  }
+}
+
+/// EmitMonoLSDA - Mono's version of EmitExceptionTable
+///
+/// The code below is a modified/simplified version of DwarfException::EmitExceptionTable()
+/// We emit the information inline instead of into a separate section.
+///
+void DwarfMonoException::EmitMonoLSDA(const FunctionEHFrameInfo *EFI) {
+  // Load saved information from EHFrameInfo
+  const MonoEHFrameInfo *MonoEH = &EFI->MonoEH;
+  const std::vector<const GlobalVariable *> &TypeInfos = MonoEH->TypeInfos;
+  const std::vector<LandingPadInfo> &PadInfos = MonoEH->PadInfos;
+  const std::vector<MonoCallSiteEntry> CallSites = MonoEH->CallSites;
+  int FunctionNumber = MonoEH->FunctionNumber;
+  int FrameReg = MonoEH->FrameReg;
+  int ThisOffset = MonoEH->ThisOffset;
+
+  // Sort the landing pads in order of their type ids.  This is used to fold
+  // duplicate actions.
+  SmallVector<const LandingPadInfo *, 64> LandingPads;
+  LandingPads.reserve(PadInfos.size());
+
+  for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
+    LandingPads.push_back(&PadInfos[i]);
+
+  std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
+
+  // Invokes and nounwind calls have entries in PadMap (due to being bracketed
+  // by try-range labels when lowered).  Ordinary calls do not, so appropriate
+  // try-ranges for them need be deduced when using DWARF exception handling.
+  RangeMapType PadMap;
+  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
+    const LandingPadInfo *LandingPad = LandingPads[i];
+    for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
+      MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
+      assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
+      PadRange P = { i, j };
+      PadMap[BeginLabel] = P;
+    }
+  }
+
+  assert(Asm->MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI);
+
+  // The type_info itself is emitted
+  int TTypeEncoding = dwarf::DW_EH_PE_udata4;
+
+  // Emit the LSDA.
+  // Keep this in sync with JITDwarfEmitter::EmitExceptionTable ()
+  Asm->EmitULEB128(0x4d4fef4f, "MONO Magic", 0);
+  Asm->EmitULEB128(1, "Version", 0);
+
+  // Emit the LSDA header.
+  if (FrameReg != -1) {
+    Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "This encoding");
+
+    // Emit 'this' location
+    Asm->OutStreamer.AddComment("bregx");
+    Asm->EmitInt8((int)dwarf::DW_OP_bregx);
+    Asm->EmitULEB128(FrameReg, "Base reg");
+    Asm->EmitSLEB128(ThisOffset, "Offset");
+  } else {
+    Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@This encoding");
+  }
+
+  Asm->EmitULEB128 (CallSites.size (), "Number of call sites");
+  Asm->EmitAlignment(2);
+  for (std::vector<MonoCallSiteEntry>::const_iterator
+         I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
+    const MonoCallSiteEntry &S = *I;
+      
+    MCSymbol *EHFuncBeginSym =
+      Asm->GetTempSymbol("eh_func_begin", FunctionNumber);
+      
+    MCSymbol *BeginLabel = S.BeginLabel;
+    if (BeginLabel == 0)
+      BeginLabel = EHFuncBeginSym;
+    MCSymbol *EndLabel = S.EndLabel;
+    if (EndLabel == 0)
+      EndLabel = Asm->GetTempSymbol("eh_func_end", FunctionNumber);
+        
+    Asm->OutStreamer.AddComment("Region start");
+    Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4);
+      
+    Asm->OutStreamer.AddComment("Region length");
+    Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
+
+    Asm->OutStreamer.AddComment("Landing pad");
+    if (!S.PadLabel)
+      Asm->OutStreamer.EmitIntValue(0, 4);
+    else
+      Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4);
+
+	unsigned int TypeID = S.TypeID;
+    assert (TypeID > 0 && TypeID <= TypeInfos.size ());
+    const GlobalVariable *GV = TypeInfos[TypeID - 1];
+    assert (GV);
+
+    //
+    // Mono typeinfos are simple constant integers. Emit the constant itself.
+    //
+    assert(GV);
+    const ConstantInt *ci = dyn_cast<ConstantInt>(GV->getInitializer());
+
+    Asm->OutStreamer.AddComment("TypeInfo");
+    Asm->OutStreamer.EmitIntValue(ci->getZExtValue(),Asm->GetSizeOfEncodedValue(TTypeEncoding));
+  }
+}
+
+// EmitMonoEHFrame - Emit Mono specific exception handling tables
+void DwarfMonoException::EmitMonoEHFrame(const Function *Personality)
+{
+  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+
+  unsigned FuncAddrEncoding = TLOF.getMonoEHTableEncoding ();
+
+  // Size and sign of stack growth.
+  int stackGrowth = Asm->getDataLayout().getPointerSize();
+  if (Asm->TM.getFrameLowering()->getStackGrowthDirection() ==
+      TargetFrameLowering::StackGrowsDown)
+    stackGrowth *= -1;
+
+  MCStreamer& Streamer = Asm->OutStreamer;
+
+  //
+  // The Mono runtime obtains EH info for LLVM JITted code by decoding the GNU EH frame
+  // created by LLVM. For static compilation, this has certain problems:
+  // - .eh_frame resides in a different segment, which makes it impossible to read it at
+  // runtime on some platforms, like the iphone
+  // - the iphone linker can't generate .eh_frame_hdr
+  // - the table is very verbose, a single FDE is about 20-24 bytes on arm, negating any
+  // code size gains obtained by using LLVM.
+  // - the information is spread across three data structures: the eh_frame, the LSDA and
+  //   type_info, which are potentially in different sections/segments, leading to relocation/
+  //   linking problems.
+  // An alternative would be using the official ARM EH tables. This has problems too:
+  // - it is also in a separate section
+  // - it is very badly specified
+  // - it needs GNU assembler/linker support to work.
+  //
+  // To solve these problems, we generate our own custom EH tables:
+  // - the table is in the rodata segment, pointed to by a local symbol.
+  // - it contains an .eh_frame_hdr style lookup table.
+  // - the LSDA and type_info are embedded into the FDE entries.
+  //
+  // http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html
+  //
+  // It is hard to get smaller tables without assembler support, since we can't encode
+  // offsets in less that 4 bytes, can't encode information into the upper bits of offsets etc.
+  //
+
+  // Can't use rodata as the symbols we reference are in the text segment
+  Streamer.SwitchSection(TLOF.getTextSection());
+
+  MCSymbol *EHFrameHdrSym =
+	  Asm->OutContext.GetOrCreateSymbol(Twine("mono_eh_frame"));
+  MCSymbol *EHFrameEndSym = Asm->GetTempSymbol ("mono_eh_frame_end");
+
+  Asm->EmitAlignment(4);
+  Streamer.EmitLabel(EHFrameHdrSym);
+  const MCExpr *Length = MakeStartMinusEndExpr(Streamer, *EHFrameHdrSym,
+                                               *EHFrameEndSym, 0);
+  if (Asm->MAI->hasDotTypeDotSizeDirective()) {
+    Streamer.EmitELFSize(EHFrameHdrSym, Length);
+    Streamer.EmitSymbolAttribute(EHFrameHdrSym, MCSA_ELF_TypeObject);
+  }
+
+  // Header
+
+  Streamer.AddComment("version");
+  Asm->OutStreamer.EmitIntValue(3, 1);
+  Asm->OutStreamer.AddComment ("func addr encoding");
+  Asm->OutStreamer.EmitIntValue (FuncAddrEncoding, 1);
+
+  // Search table
+  Asm->EmitAlignment(2);
+  Streamer.AddComment("fde_count");
+  Streamer.EmitIntValue (EHFrames.size(), 4);
+  for (std::vector<FunctionEHFrameInfo>::iterator
+		   I = EHFrames.begin(), E = EHFrames.end(); I != E; ++I) {
+	  const FunctionEHFrameInfo &EHFrameInfo = *I;
+
+      //
+      // Instead of the function address, we emit the mono method index, which is easier to encode.
+      //
+      Streamer.AddComment("mono method idx");
+      Streamer.EmitIntValue (EHFrameInfo.MonoEH.MonoMethodIdx, 4);
+	  MCSymbol *FDEBeginSym = Asm->GetTempSymbol ("mono_eh_func_begin", EHFrameInfo.Number);
+	  Asm->EmitLabelDifference(FDEBeginSym, EHFrameHdrSym, 4);
+  }
+  // Emit a last entry to simplify binary searches and to enable the computation of
+  // the size of the last function/FDE entry
+  if (EHFrames.size() == 0) {
+	  Streamer.EmitIntValue (-1, 4);
+	  Asm->EmitLabelDifference(EHFrameHdrSym, EHFrameHdrSym, 4);
+  } else {
+	  // Emit the size of the last function, since it cannot be computed using the next table entry
+	  MCSymbol *Sym1 = Asm->GetTempSymbol("eh_func_begin", EHFrames.size() - 1);
+	  MCSymbol *Sym2 = Asm->GetTempSymbol("eh_func_end", EHFrames.size() - 1);
+	  Asm->EmitLabelDifference(Sym2, Sym1, 4);
+	  MCSymbol *Sym3 = Asm->GetTempSymbol ("mono_eh_frame_end");
+	  Asm->EmitLabelDifference(Sym3, EHFrameHdrSym, 4);
+  }
+
+  // CIE
+  // This comes right after the search table
+  Asm->EmitULEB128(1, "CIE Code Alignment Factor");
+  Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
+  Streamer.AddComment("CIE Return Address Column");
+  const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
+  Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
+
+  Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "Personality");
+
+  int CFAOffset = 0;
+
+  int dataAlignmentFactor = stackGrowth;
+
+  // Initial CIE program
+  EmitCFIInstructions(Streamer, Streamer.getContext().getAsmInfo()->getInitialFrameState(), NULL, CFAOffset, dataAlignmentFactor);
+
+  int CIECFAOffset = CFAOffset;
+
+  // FDEs
+  Streamer.AddBlankLine();
+  for (std::vector<FunctionEHFrameInfo>::iterator
+		   I = EHFrames.begin(), E = EHFrames.end(); I != E; ++I) {
+	  const FunctionEHFrameInfo &EHFrameInfo = *I;
+      int Index = EHFrameInfo.Number;
+
+	  MCSymbol *FDEBeginSym = Asm->GetTempSymbol ("mono_eh_func_begin", Index);
+      Streamer.EmitLabel(FDEBeginSym);
+
+      // No need for length, CIE, PC begin, PC range, alignment
+
+      // Emit augmentation
+      if (EHFrameInfo.hasLandingPads) {
+        // Need an extra has_augmentation field as the augmentation size is always encoded
+        // in 4 bytes
+        Asm->EmitULEB128(1, "Has augmentation");
+
+        Streamer.AddComment("Augmentation size");
+        Asm->EmitLabelDifference(Asm->GetTempSymbol("mono_fde_aug_end", Index),
+                                 Asm->GetTempSymbol("mono_fde_aug_begin", Index),
+                                 4);
+
+        Streamer.EmitLabel(Asm->GetTempSymbol("mono_fde_aug_begin", Index));
+        EmitMonoLSDA (&EHFrameInfo);
+        Streamer.EmitLabel(Asm->GetTempSymbol("mono_fde_aug_end", Index));
+      } else {
+        Asm->EmitULEB128(0, "Has augmentation");
+      }
+
+      CFAOffset = CIECFAOffset;
+
+      EmitCFIInstructions(Streamer, EHFrameInfo.Instructions, NULL, CFAOffset, dataAlignmentFactor);
+
+      Streamer.AddBlankLine();
+  }
+
+  Streamer.EmitLabel(EHFrameEndSym);
+}
+
+DwarfMonoException::DwarfMonoException(AsmPrinter *A)
+  : DwarfException(A) {}
+
+DwarfMonoException::~DwarfMonoException() {}
+
+void DwarfMonoException::BeginFunction(const MachineFunction *MF)
+{
+  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
+                                                Asm->getFunctionNumber()));
+}
+
+void DwarfMonoException::EndFunction() {
+  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
+                                                Asm->getFunctionNumber()));
+
+  MMI->TidyLandingPads();
+
+  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+  MCSymbol *FunctionEHSym =
+    Asm->GetSymbolWithGlobalValueBase(Asm->MF->getFunction(), ".eh",
+                                      TLOF.isFunctionEHFrameSymbolPrivate());
+
+  // Save EH frame information
+  FunctionEHFrameInfo EHFrameInfo =
+    FunctionEHFrameInfo(FunctionEHSym,
+                        Asm->getFunctionNumber(),
+                        MMI->getPersonalityIndex(),
+                        Asm->MF->getFrameInfo()->adjustsStack(),
+                        !MMI->getLandingPads().empty(),
+                        MMI->getFrameInstructions(),
+                        Asm->MF->getFunction());
+
+  PrepareMonoLSDA(&EHFrameInfo);
+
+  EHFrames.push_back(EHFrameInfo);
+}
+
+void DwarfMonoException::EndModule() {
+  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+
+  // Emit references to all used personality functions
+  const std::vector<const Function*> &Personalities = MMI->getPersonalities();
+  for (size_t i = 0, e = Personalities.size(); i != e; ++i) {
+    if (!Personalities[i])
+      continue;
+    MCSymbol *Sym = TLOF.getSymbol(*Asm->Mang, Personalities[i]);
+    TLOF.emitPersonalityValue(Asm->OutStreamer, Asm->TM, Sym);
+  }
+
+  EmitMonoEHFrame(Personalities[0]);
+}

Modified: lib/CodeGen/MachineFunction.cpp
===================================================================
@@ -25,6 +25,7 @@
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MonoMachineFunctionInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/DebugInfo.h"
 #include "llvm/IR/DataLayout.h"
@@ -60,6 +61,7 @@
     RegInfo = 0;
 
   MFInfo = 0;
+  MonoInfo = 0;
   FrameInfo =
     new (Allocator) MachineFrameInfo(TM,!F->hasFnAttribute("no-realign-stack"));
 
@@ -69,6 +71,7 @@
                                 getStackAlignment(AttributeSet::FunctionIndex));
 
   ConstantPool = new (Allocator) MachineConstantPool(TM);
+  MonoInfo = new (Allocator) MonoMachineFunctionInfo(*this);
   Alignment = TM.getTargetLowering()->getMinFunctionAlignment();
 
   // FIXME: Shouldn't use pref alignment if explicit alignment is set on Fn.
@@ -100,6 +103,10 @@
     MFInfo->~MachineFunctionInfo();
     Allocator.Deallocate(MFInfo);
   }
+  if (MonoInfo) {
+    MonoInfo->~MonoMachineFunctionInfo();
+    Allocator.Deallocate(MonoInfo);
+  }
 
   FrameInfo->~MachineFrameInfo();
   Allocator.Deallocate(FrameInfo);

Modified: lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
===================================================================
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MonoMachineFunctionInfo.h"
 #include "llvm/DebugInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -95,6 +96,19 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) {
         StaticAllocaMap[AI] =
           MF->getFrameInfo()->CreateStackObject(TySize, Align, false,
                                                 MayNeedSP, AI);
+
+        //
+        // The mono exception handling code needs to location of the 'this' pointer
+        // to handle stack traces containing generic shared methods.
+        // To implement this, it saves the this pointer to an alloca which is marked with
+        // the 'mono.this' custom metadata. We save the stack slot used by this alloca
+        // in MachineFunction, so the dwarf exception info emission code can use it to
+        // compute the reg+offset for it, and save it into the LSDA.
+        //
+        if (AI->getMetadata("mono.this")) {
+          MonoMachineFunctionInfo *MonoFI = MF->getMonoInfo();
+          MonoFI->setThisStackSlot (StaticAllocaMap[AI]);
+        }
       }
 
   for (; BB != EB; ++BB)

Modified: lib/ExecutionEngine/ExecutionEngine.cpp
===================================================================
@@ -56,7 +56,9 @@
 
 ExecutionEngine::ExecutionEngine(Module *M)
   : EEState(*this),
-    LazyFunctionCreator(0) {
+    LazyFunctionCreator(0),
+    ExceptionTableRegister(0),
+    ExceptionTableDeregister(0) {
   CompilingLazily         = false;
   GVCompilationDisabled   = false;
   SymbolSearchingDisabled = false;
@@ -70,6 +72,16 @@
     delete Modules[i];
 }
 
+void ExecutionEngine::DeregisterAllTables() {
+  if (ExceptionTableDeregister) {
+    DenseMap<const Function*, void*>::iterator it = AllExceptionTables.begin();
+    DenseMap<const Function*, void*>::iterator ite = AllExceptionTables.end();
+    for (; it != ite; ++it)
+      ExceptionTableDeregister(it->second);
+    AllExceptionTables.clear();
+  }
+}
+
 namespace {
 /// \brief Helper class which uses a value handler to automatically deletes the
 /// memory block when the GlobalVariable is destroyed.

Modified: lib/ExecutionEngine/JIT/CMakeLists.txt
===================================================================
@@ -3,6 +3,7 @@ add_definitions(-DENABLE_X86_JIT)
 
 add_llvm_library(LLVMJIT
   JIT.cpp
+  JITDwarfEmitter.cpp
   JITEmitter.cpp
   JITMemoryManager.cpp
   )

Modified: lib/ExecutionEngine/JIT/JIT.cpp
===================================================================
@@ -610,6 +610,9 @@ void *JIT::getOrEmitGlobalVariable(const GlobalVariable *GV) {
     // If the global hasn't been emitted to memory yet, allocate space and
     // emit it into memory.
     Ptr = getMemoryForGV(GV);
+    if (Ptr == 0)
+       // Buffer overflow
+       return NULL;
     addGlobalMapping(GV, Ptr);
     EmitGlobalVariable(GV);  // Initialize the variable.
   }

Added: lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
===================================================================
@@ -0,0 +1,442 @@
+//===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a JITDwarfEmitter object that is used by the JIT to
+// write dwarf tables to memory.
+//
+//===----------------------------------------------------------------------===//
+
+#include "JITDwarfEmitter.h"
+#include "JIT.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/JITCodeEmitter.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MonoMachineFunctionInfo.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MachineLocation.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+using namespace llvm;
+
+JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : MMI(0), Jit(theJit) {}
+
+
+unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F,
+                                               JITCodeEmitter& jce,
+                                               unsigned char* StartFunction,
+                                               unsigned char* EndFunction,
+                                               unsigned char* &EHFramePtr) {
+  assert(MMI && "MachineModuleInfo not registered!");
+
+  const TargetMachine& TM = F.getTarget();
+  TD = TM.getDataLayout();
+  stackGrowthDirection = TM.getFrameLowering()->getStackGrowthDirection();
+  RI = TM.getRegisterInfo();
+  MAI = TM.getMCAsmInfo();
+  JCE = &jce;
+
+  unsigned char* ExceptionTable = EmitMonoLSDA(&F, StartFunction,
+                                               EndFunction);
+
+  unsigned char* Result = 0;
+
+  const std::vector<const Function *> Personalities = MMI->getPersonalities();
+  EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
+
+  Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
+                       StartFunction, EndFunction, ExceptionTable);
+
+  return Result;
+}
+
+void
+JITDwarfEmitter::EmitCFIInstructions(intptr_t BaseLabelPtr,
+                                const std::vector<MCCFIInstruction> &Instructions) const {
+  unsigned PointerSize = TD->getPointerSize();
+  int stackGrowth = stackGrowthDirection == TargetFrameLowering::StackGrowsUp ?
+          PointerSize : -PointerSize;
+  MCSymbol *BaseLabel = 0;
+
+  for (unsigned i = 0, N = Instructions.size(); i < N; ++i) {
+    const MCCFIInstruction &Instr = Instructions[i];
+    MCSymbol *Label = Instr.getLabel();
+
+    // Throw out move if the label is invalid.
+    if (Label && (*JCE->getLabelLocations())[Label] == 0)
+      continue;
+
+    intptr_t LabelPtr = 0;
+    if (Label) LabelPtr = JCE->getLabelAddress(Label);
+
+    // Advance row if new location.
+    if (BaseLabelPtr && Label && BaseLabel != Label) {
+      JCE->emitByte(dwarf::DW_CFA_advance_loc4);
+      JCE->emitInt32(LabelPtr - BaseLabelPtr);
+
+      BaseLabel = Label;
+      BaseLabelPtr = LabelPtr;
+    }
+
+	// Similar to FrameEmitterImpl::EmitCFIInstruction () in MCDwarf.cpp
+    switch (Instr.getOperation()) {
+    case MCCFIInstruction::OpDefCfaOffset: {
+      JCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
+      JCE->emitULEB128Bytes(Instr.getOffset());
+      break;
+    }
+    case MCCFIInstruction::OpDefCfa: {
+      JCE->emitByte(dwarf::DW_CFA_def_cfa);
+      JCE->emitULEB128Bytes(Instr.getRegister());
+      JCE->emitULEB128Bytes(-Instr.getOffset());
+      break;
+    }
+    case MCCFIInstruction::OpDefCfaRegister: {
+      JCE->emitByte(dwarf::DW_CFA_def_cfa_register);
+      JCE->emitULEB128Bytes(Instr.getRegister());
+      break;
+    }
+    case MCCFIInstruction::OpOffset: {
+      unsigned Reg = Instr.getRegister();
+      int Offset = Instr.getOffset() / stackGrowth;
+
+      if (Offset < 0) {
+        JCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
+        JCE->emitULEB128Bytes(Reg);
+        JCE->emitSLEB128Bytes(Offset);
+      } else if (Reg < 64) {
+        JCE->emitByte(dwarf::DW_CFA_offset + Reg);
+        JCE->emitULEB128Bytes(Offset);
+      } else {
+        JCE->emitByte(dwarf::DW_CFA_offset_extended);
+        JCE->emitULEB128Bytes(Reg);
+        JCE->emitULEB128Bytes(Offset);
+      }
+      break;
+    }
+    default:
+      llvm_unreachable("Unhandled case in switch");
+    }
+  }
+}
+
+/// PadLT - Order landing pads lexicographically by type id.
+static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
+  const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
+  unsigned LSize = LIds.size(), RSize = RIds.size();
+  unsigned MinSize = LSize < RSize ? LSize : RSize;
+
+  for (unsigned i = 0; i != MinSize; ++i)
+    if (LIds[i] != RIds[i])
+      return LIds[i] < RIds[i];
+
+  return LSize < RSize;
+}
+
+namespace {
+
+/// PadRange - Structure holding a try-range and the associated landing pad.
+struct PadRange {
+  // The index of the landing pad.
+  unsigned PadIndex;
+  // The index of the begin and end labels in the landing pad's label lists.
+  unsigned RangeIndex;
+};
+
+typedef DenseMap<MCSymbol*, PadRange> RangeMapType;
+
+/// CallSiteEntry - Structure describing an entry in the call-site table.
+struct CallSiteEntry {
+  MCSymbol *BeginLabel; // zero indicates the start of the function.
+  MCSymbol *EndLabel;   // zero indicates the end of the function.
+  MCSymbol *PadLabel;   // zero indicates that there is no landing pad.
+  int TypeID;
+};
+
+}
+
+unsigned char* JITDwarfEmitter::EmitMonoLSDA(MachineFunction* MF,
+                                             unsigned char* StartFunction,
+                                             unsigned char* EndFunction) const {
+  assert(MMI && "MachineModuleInfo not registered!");
+
+  // Map all labels and get rid of any dead landing pads.
+  MMI->TidyLandingPads(JCE->getLabelLocations());
+
+  const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
+  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
+
+  int ThisSlot = MF->getMonoInfo()->getThisStackSlot();
+
+  if (PadInfos.empty() && ThisSlot == -1)
+    return 0;
+
+  // Sort the landing pads in order of their type ids.  This is used to fold
+  // duplicate actions.
+  SmallVector<const LandingPadInfo *, 64> LandingPads;
+  LandingPads.reserve(PadInfos.size());
+  for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
+    LandingPads.push_back(&PadInfos[i]);
+  std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
+
+  // Compute the call-site table.  Entries must be ordered by address.
+  SmallVector<CallSiteEntry, 64> CallSites;
+
+  RangeMapType PadMap;
+  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
+    const LandingPadInfo *LandingPad = LandingPads[i];
+    for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
+      MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
+      assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
+      PadRange P = { i, j };
+      PadMap[BeginLabel] = P;
+    }
+  }
+
+  MCSymbol *LastLabel = 0;
+  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+        I != E; ++I) {
+    for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
+          MI != E; ++MI) {
+      if (!MI->isLabel()) {
+        continue;
+      }
+
+      MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol();
+      assert(BeginLabel && "Invalid label!");
+
+      RangeMapType::iterator L = PadMap.find(BeginLabel);
+
+      if (L == PadMap.end())
+        continue;
+
+      PadRange P = L->second;
+      const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
+
+      assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
+              "Inconsistent landing pad map!");
+
+      // Mono emits one landing pad for each CLR exception clause,
+      // and the type info contains the clause index
+      assert (LandingPad->TypeIds.size() == 1);
+      assert (LandingPad->LandingPadLabel);
+
+      LastLabel = LandingPad->EndLabels[P.RangeIndex];
+      CallSiteEntry Site = {BeginLabel, LastLabel,
+							LandingPad->LandingPadLabel, LandingPad->TypeIds [0]};
+
+      assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
+              "Invalid landing pad!");
+
+      // Try to merge with the previous call-site.
+      if (CallSites.size()) {
+        CallSiteEntry &Prev = CallSites.back();
+        if (Site.PadLabel == Prev.PadLabel && Site.TypeID == Prev.TypeID) {
+          // Extend the range of the previous entry.
+          Prev.EndLabel = Site.EndLabel;
+          continue;
+        }
+      }
+
+      // Otherwise, create a new call-site.
+      CallSites.push_back(Site);
+    }
+  }
+
+  // Begin the exception table.
+  JCE->emitAlignmentWithFill(4, 0);
+
+  unsigned char* DwarfExceptionTable = (unsigned char*)JCE->getCurrentPCValue();
+
+  // Keep this in sync with DwarfMonoException::EmitMonoLSDA ()
+
+  // Emit the header.
+  JCE->emitULEB128Bytes(0x4d4fef4f);
+  JCE->emitULEB128Bytes(1);
+
+  if (ThisSlot != -1) {
+    // Emit 'this' location
+    unsigned FrameReg;
+    int Offset = MF->getTarget ().getFrameLowering ()->getFrameIndexReference (*MF, ThisSlot, FrameReg);
+    FrameReg = MF->getTarget ().getRegisterInfo ()->getDwarfRegNum (FrameReg, true);
+
+	JCE->emitByte(dwarf::DW_EH_PE_udata4);
+    JCE->emitByte((int)dwarf::DW_OP_bregx);
+    JCE->emitULEB128Bytes(FrameReg);
+    JCE->emitSLEB128Bytes(Offset);
+  } else {
+    JCE->emitByte(dwarf::DW_EH_PE_omit);
+  }
+
+  JCE->emitULEB128Bytes (CallSites.size ());
+  JCE->emitAlignmentWithFill(4, 0);
+
+  // Emit the landing pad site information.
+  for (unsigned i = 0; i < CallSites.size(); ++i) {
+    CallSiteEntry &S = CallSites[i];
+    intptr_t BeginLabelPtr = 0;
+    intptr_t EndLabelPtr = 0;
+
+    if (!S.BeginLabel) {
+      BeginLabelPtr = (intptr_t)StartFunction;
+      JCE->emitInt32(0);
+    } else {
+      BeginLabelPtr = JCE->getLabelAddress(S.BeginLabel);
+      JCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
+    }
+
+    if (!S.EndLabel)
+      EndLabelPtr = (intptr_t)EndFunction;
+    else
+      EndLabelPtr = JCE->getLabelAddress(S.EndLabel);
+
+    JCE->emitInt32(EndLabelPtr - BeginLabelPtr);
+
+    if (!S.PadLabel) {
+      JCE->emitInt32(0);
+    } else {
+      unsigned PadLabelPtr = JCE->getLabelAddress(S.PadLabel);
+      JCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
+    }
+
+	unsigned int TypeID = S.TypeID;
+    assert (TypeID > 0 && TypeID <= TypeInfos.size ());
+    const GlobalVariable *GV = TypeInfos[TypeID - 1];
+    assert (GV);
+    int ClauseIndex = *(int*)Jit.getOrEmitGlobalVariable(GV);
+    JCE->emitInt32 (ClauseIndex);
+  }
+
+  JCE->emitAlignmentWithFill(4, 0);
+
+  return DwarfExceptionTable;
+}
+
+unsigned char*
+JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
+  unsigned PointerSize = TD->getPointerSize();
+  int stackGrowth = stackGrowthDirection == TargetFrameLowering::StackGrowsUp ?
+          PointerSize : -PointerSize;
+
+  unsigned char* StartCommonPtr = (unsigned char*)JCE->getCurrentPCValue();
+  // EH Common Frame header
+  JCE->allocateSpace(4, 0);
+  unsigned char* FrameCommonBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
+  JCE->emitInt32((int)0);
+  JCE->emitByte(dwarf::DW_CIE_VERSION);
+  JCE->emitString(Personality ? "zPLR" : "zR");
+  JCE->emitULEB128Bytes(1);
+  JCE->emitSLEB128Bytes(stackGrowth);
+  JCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
+
+  if (Personality) {
+    // Augmentation Size: 3 small ULEBs of one byte each, and the personality
+    // function which size is PointerSize.
+    JCE->emitULEB128Bytes(3 + PointerSize);
+
+    // We set the encoding of the personality as direct encoding because we use
+    // the function pointer. The encoding is not relative because the current
+    // PC value may be bigger than the personality function pointer.
+    if (PointerSize == 4) {
+      JCE->emitByte(dwarf::DW_EH_PE_sdata4);
+      JCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality)));
+    } else {
+      JCE->emitByte(dwarf::DW_EH_PE_sdata8);
+      JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality)));
+    }
+
+    // LSDA encoding: This must match the encoding used in EmitEHFrame ()
+    if (PointerSize == 4)
+      JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
+    else
+      JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8);
+    JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
+  } else {
+    JCE->emitULEB128Bytes(1);
+    JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
+  }
+
+  EmitCFIInstructions(0, MAI->getInitialFrameState());
+
+  JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop);
+
+  JCE->emitInt32At((uintptr_t*)StartCommonPtr,
+                   (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() -
+                               FrameCommonBeginPtr));
+
+  return StartCommonPtr;
+}
+
+
+unsigned char*
+JITDwarfEmitter::EmitEHFrame(const Function* Personality,
+                             unsigned char* StartCommonPtr,
+                             unsigned char* StartFunction,
+                             unsigned char* EndFunction,
+                             unsigned char* ExceptionTable) const {
+  unsigned PointerSize = TD->getPointerSize();
+
+  // EH frame header.
+  unsigned char* StartEHPtr = (unsigned char*)JCE->getCurrentPCValue();
+  JCE->allocateSpace(4, 0);
+  unsigned char* FrameBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
+  // FDE CIE Offset
+  JCE->emitInt32(FrameBeginPtr - StartCommonPtr);
+  JCE->emitInt32(StartFunction - (unsigned char*)JCE->getCurrentPCValue());
+  JCE->emitInt32(EndFunction - StartFunction);
+
+  // If there is a personality and landing pads then point to the language
+  // specific data area in the exception table.
+  if (ExceptionTable) {
+    JCE->emitULEB128Bytes(PointerSize == 4 ? 4 : 8);
+
+    if (PointerSize == 4) {
+      if (ExceptionTable)
+        JCE->emitInt32(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
+      else
+        JCE->emitInt32((int)0);
+    } else {
+      if (ExceptionTable)
+        JCE->emitInt64(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
+      else
+        JCE->emitInt64((int)0);
+    }
+  } else {
+    JCE->emitULEB128Bytes(0);
+  }
+
+  EmitCFIInstructions((intptr_t)StartFunction, MMI->getFrameInstructions());
+
+  JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop);
+
+  // Indicate the size of the table
+  JCE->emitInt32At((uintptr_t*)StartEHPtr,
+                   (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() -
+                               StartEHPtr));
+
+  // Double zeroes for the unwind runtime
+  if (PointerSize == 8) {
+    JCE->emitInt64(0);
+    JCE->emitInt64(0);
+  } else {
+    JCE->emitInt32(0);
+    JCE->emitInt32(0);
+  }
+
+  return StartEHPtr;
+}

Added: lib/ExecutionEngine/JIT/JITDwarfEmitter.h
===================================================================
@@ -0,0 +1,77 @@
+//===------ JITDwarfEmitter.h - Write dwarf tables into memory ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a JITDwarfEmitter object that is used by the JIT to
+// write dwarf tables to memory.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
+#define LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class Function;
+class JIT;
+class JITCodeEmitter;
+class MachineFunction;
+class MachineModuleInfo;
+class MCCFIInstruction;
+class MCAsmInfo;
+class DataLayout;
+class TargetMachine;
+class TargetRegisterInfo;
+
+class JITDwarfEmitter {
+  const DataLayout* TD;
+  JITCodeEmitter* JCE;
+  const TargetRegisterInfo* RI;
+  const MCAsmInfo *MAI;
+  MachineModuleInfo* MMI;
+  JIT& Jit;
+  bool stackGrowthDirection;
+
+  unsigned char* EmitMonoLSDA(MachineFunction* MF,
+                              unsigned char* StartFunction,
+                              unsigned char* EndFunction) const;
+
+  void EmitCFIInstructions(intptr_t BaseLabelPtr,
+                      const std::vector<MCCFIInstruction> &Instructions) const;
+
+  unsigned char* EmitCommonEHFrame(const Function* Personality) const;
+
+  unsigned char* EmitEHFrame(const Function* Personality,
+                             unsigned char* StartBufferPtr,
+                             unsigned char* StartFunction,
+                             unsigned char* EndFunction,
+                             unsigned char* ExceptionTable) const;
+
+public:
+
+  JITDwarfEmitter(JIT& jit);
+
+  unsigned char* EmitDwarfTable(MachineFunction& F,
+                                JITCodeEmitter& JCE,
+                                unsigned char* StartFunction,
+                                unsigned char* EndFunction,
+                                unsigned char* &EHFramePtr);
+
+
+  void setModuleInfo(MachineModuleInfo* Info) {
+    MMI = Info;
+  }
+};
+
+
+} // end namespace llvm
+
+#endif // LLVM_EXECUTION_ENGINE_JIT_DWARFEMITTER_H

Modified: lib/ExecutionEngine/JIT/JITEmitter.cpp
===================================================================
@@ -14,6 +14,7 @@
 
 #define DEBUG_TYPE "jit"
 #include "JIT.h"
+#include "JITDwarfEmitter.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -324,6 +325,9 @@ static bool isNonGhostDeclaration(const Function *F) {
     /// Resolver - This contains info about the currently resolved functions.
     JITResolver Resolver;
 
+    /// DE - The dwarf emitter for the jit.
+    OwningPtr<JITDwarfEmitter> DE;
+
     /// LabelLocations - This vector is a mapping from Label ID's to their
     /// address.
     DenseMap<MCSymbol*, uintptr_t> LabelLocations;
@@ -359,16 +363,22 @@ static bool isNonGhostDeclaration(const Function *F) {
     /// Instance of the JIT
     JIT *TheJIT;
 
+    bool JITExceptionHandling;
+
   public:
     JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
       : SizeEstimate(0), Resolver(jit, *this), MMI(0), CurFn(0),
-        EmittedFunctions(this), TheJIT(&jit) {
+        EmittedFunctions(this), TheJIT(&jit),
+        JITExceptionHandling(TM.Options.JITExceptionHandling) {
       MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
       if (jit.getJITInfo().needsGOT()) {
         MemMgr->AllocateGOT();
         DEBUG(dbgs() << "JIT is managing a GOT\n");
       }
 
+      if (JITExceptionHandling) {
+        DE.reset(new JITDwarfEmitter(jit));
+      }
     }
     ~JITEmitter() {
       delete MemMgr;
@@ -450,6 +460,7 @@ static bool isNonGhostDeclaration(const Function *F) {
 
     virtual void setModuleInfo(MachineModuleInfo* Info) {
       MMI = Info;
+      if (DE.get()) DE->setModuleInfo(Info);
     }
 
   private:
@@ -953,6 +964,40 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
       }
     });
 
+  if (JITExceptionHandling) {
+    uintptr_t ActualSize = 0;
+    SavedBufferBegin = BufferBegin;
+    SavedBufferEnd = BufferEnd;
+    SavedCurBufferPtr = CurBufferPtr;
+    uint8_t *FrameRegister;
+
+    while (true) {
+      BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
+                                                               ActualSize);
+      BufferEnd = BufferBegin+ActualSize;
+      EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin;
+      uint8_t *EhStart;
+      FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, EhStart);
+
+      // If the buffer was large enough to hold the table then we are done.
+      if (CurBufferPtr != BufferEnd)
+        break;
+
+      // Try again with twice as much space.
+      ActualSize = (CurBufferPtr - BufferBegin) * 2;
+      MemMgr->deallocateExceptionTable(BufferBegin);
+    }
+    MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
+                              FrameRegister);
+    BufferBegin = SavedBufferBegin;
+    BufferEnd = SavedBufferEnd;
+    CurBufferPtr = SavedCurBufferPtr;
+
+    if (JITExceptionHandling) {
+      TheJIT->RegisterTable(F.getFunction(), FrameRegister);
+    }
+  }
+
   if (MMI)
     MMI->EndFunction();
 
@@ -982,10 +1027,15 @@ void JITEmitter::deallocateMemForFunction(const Function *F) {
     Emitted = EmittedFunctions.find(F);
   if (Emitted != EmittedFunctions.end()) {
     MemMgr->deallocateFunctionBody(Emitted->second.FunctionBody);
+    MemMgr->deallocateExceptionTable(Emitted->second.ExceptionTable);
     TheJIT->NotifyFreeingMachineCode(Emitted->second.Code);
 
     EmittedFunctions.erase(Emitted);
   }
+
+  if (JITExceptionHandling) {
+    TheJIT->DeregisterTable(F);
+  }
 }
 
 

Modified: lib/ExecutionEngine/JIT/JITMemoryManager.cpp
===================================================================
@@ -519,6 +519,26 @@ void FreeRangeHeader::GrowBlock(uintptr_t NewSize) {
       return false;
     }
 
+    /// startExceptionTable - Use startFunctionBody to allocate memory for the
+    /// function's exception table.
+    uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize) {
+      return startFunctionBody(F, ActualSize);
+    }
+
+    /// endExceptionTable - The exception table of F is now allocated,
+    /// and takes the memory in the range [TableStart,TableEnd).
+    void endExceptionTable(const Function *F, uint8_t *TableStart,
+                           uint8_t *TableEnd, uint8_t* FrameRegister) {
+      assert(TableEnd > TableStart);
+      assert(TableStart == (uint8_t *)(CurBlock+1) &&
+             "Mismatched table start/end!");
+
+      uintptr_t BlockSize = TableEnd - (uint8_t *)CurBlock;
+
+      // Release the memory at the end of this block that isn't needed.
+      FreeMemoryList =CurBlock->TrimAllocationToSize(FreeMemoryList, BlockSize);
+    }
+
     uint8_t *getGOTBase() const {
       return GOTBase;
     }
@@ -543,6 +563,12 @@ void FreeRangeHeader::GrowBlock(uintptr_t NewSize) {
       if (Body) deallocateBlock(Body);
     }
 
+    /// deallocateExceptionTable - Deallocate memory for the specified
+    /// exception table.
+    void deallocateExceptionTable(void *ET) {
+      if (ET) deallocateBlock(ET);
+    }
+
     /// setMemoryWritable - When code generation is in progress,
     /// the code pages may need permissions changed.
     void setMemoryWritable()

Modified: lib/MC/MCObjectFileInfo.cpp
===================================================================
@@ -27,6 +27,11 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
   TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
     dwarf::DW_EH_PE_sdata4;
 
+  if (T.getOS() == Triple::IOS)
+    MonoEHTableEncoding = dwarf::DW_EH_PE_absptr;
+  else
+    MonoEHTableEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+
   // .comm doesn't support alignment before Leopard.
   if (T.isMacOSX() && T.isMacOSXVersionLT(10, 5))
     CommDirectiveSupportsAlignment = false;
@@ -326,6 +331,11 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
       FDEEncoding = dwarf::DW_EH_PE_absptr;
       TTypeEncoding = dwarf::DW_EH_PE_absptr;
     }
+  } else if (T.getArch() == Triple::arm) {
+    PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+    LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+    FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+    TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
   }
 
   // Solaris requires different flags for .eh_frame to seemingly every other
@@ -339,6 +349,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
       EHSectionFlags |= ELF::SHF_WRITE;
   }
 
+  MonoEHTableEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
 
   // ELF
   BSSSection =

Modified: lib/Transforms/Scalar/GlobalMerge.cpp
===================================================================
@@ -266,6 +266,8 @@ bool GlobalMerge::doInitialization(Module &M) {
     if (isMustKeepGlobalVariable(I))
       continue;
 
+    // FIXME: This merges Mono's type_info globals, breaking EH
+/*
     if (TD->getTypeAllocSize(Ty) < MaxOffset) {
       if (TargetLoweringObjectFile::getKindForGlobal(I, TLI->getTargetMachine())
           .isBSSLocal())
@@ -275,6 +277,7 @@ bool GlobalMerge::doInitialization(Module &M) {
       else
         Globals[AddressSpace].push_back(I);
     }
+*/
   }
 
   for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator

Modified: tools/lli/RemoteMemoryManager.h
===================================================================
@@ -107,6 +107,19 @@ class RemoteMemoryManager : public JITMemoryManager {
   uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
   uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
   void deallocateFunctionBody(void *Body);
+
+  virtual uint8_t *startExceptionTable(const Function *F,
+                                       uintptr_t &ActualSize) {
+    llvm_unreachable("Unexpected call!");
+    return 0;
+  }
+  virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
+                                 uint8_t *TableEnd, uint8_t *FrameRegister) {
+    llvm_unreachable("Unexpected call!");
+  }
+  virtual void deallocateExceptionTable(void *ET) {
+    llvm_unreachable("Unexpected call!");
+  }
 };
 
 } // end namespace llvm

Modified: unittests/ExecutionEngine/JIT/JITTest.cpp
===================================================================
@@ -163,6 +163,19 @@ class RecordingJITMemoryManager : public JITMemoryManager {
     deallocateFunctionBodyCalls.push_back(DeallocateFunctionBodyCall(Body));
     Base->deallocateFunctionBody(Body);
   }
+
+  virtual uint8_t *startExceptionTable(const Function *F,
+                                       uintptr_t &ActualSize) {
+    llvm_unreachable("Unexpected call!");
+    return 0;
+  }
+  virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
+                                 uint8_t *TableEnd, uint8_t *FrameRegister) {
+    llvm_unreachable("Unexpected call!");
+  }
+  virtual void deallocateExceptionTable(void *ET) {
+    llvm_unreachable("Unexpected call!");
+  }
 };
 
 bool LoadAssemblyInto(Module *M, const char *assembly) {

   Commit: f3ed231699d5ce64ad9635b39c1c20d3bd8684f0
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:25:04 GMT
      URL: https://github.com/mono/llvm/commit/f3ed231699d5ce64ad9635b39c1c20d3bd8684f0

Workaround some problems in the ARMConstantIsland pass.

Changed paths:
  M lib/Target/ARM/ARMConstantIslandPass.cpp

Modified: lib/Target/ARM/ARMConstantIslandPass.cpp
===================================================================
@@ -777,7 +777,8 @@ void ARMConstantIslands::scanFunctionJumpTables() {
           // Remember that this is a user of a CP entry.
           unsigned CPI = I->getOperand(op).getIndex();
           MachineInstr *CPEMI = CPEMIs[CPI];
-          unsigned MaxOffs = ((1 << Bits)-1) * Scale;
+          // Substract 64 as a workaround for overflow problems when targeting thumb2
+          unsigned MaxOffs = (((1 << Bits)-1) * Scale) - 64;
           CPUsers.push_back(CPUser(I, CPEMI, MaxOffs, NegOk, IsSoImm));
 
           // Increment corresponding CPEntry reference count.
@@ -1936,6 +1937,10 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
 
       DEBUG(dbgs() << "Shrink JT: " << *MI << "     addr: " << *AddrMI
                    << "      lea: " << *LeaMI);
+
+      // The .byte directives generated by this optimization sometimes overflow
+      continue;
+
       unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT;
       MachineInstr *NewJTMI = BuildMI(MBB, MI->getDebugLoc(), TII->get(Opc))
         .addReg(IdxReg, getKillRegState(IdxRegKill))

   Commit: f7df56e929ae8177db8e590a51da5760ec3f4687
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:25:11 GMT
      URL: https://github.com/mono/llvm/commit/f7df56e929ae8177db8e590a51da5760ec3f4687

Add a mono specific flag in the form of custom metadata, toh make it possible/easier for LLVM to hoist loads out of loops.

Changed paths:
  M lib/Analysis/ValueTracking.cpp

Modified: lib/Analysis/ValueTracking.cpp
===================================================================
@@ -2008,6 +2008,11 @@ bool llvm::isSafeToSpeculativelyExecute(const Value *V,
     const LoadInst *LI = cast<LoadInst>(Inst);
     if (!LI->isUnordered())
       return false;
+    //
+    // Mono extension, the metadata identifies loads which can't fail.
+    //
+    if (LI->getMetadata("mono.nofail.load"))
+      return true;
     return LI->getPointerOperand()->isDereferenceablePointer();
   }
   case Instruction::Call: {

   Commit: 7ce97e358228c272a971230a2483355080fb1d4a
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:25:19 GMT
      URL: https://github.com/mono/llvm/commit/7ce97e358228c272a971230a2483355080fb1d4a

Generate DWARF CFI unwind info on arm.

Changed paths:
  M lib/Target/ARM/ARMFrameLowering.cpp
  M lib/Target/ARM/Thumb1FrameLowering.cpp

Modified: lib/Target/ARM/ARMFrameLowering.cpp
===================================================================
@@ -20,6 +20,7 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/RegisterScavenging.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Function.h"
@@ -108,6 +109,9 @@ static bool isCSRestore(MachineInstr *MI,
       MI->getOperand(1).getReg() == ARM::SP)
     return true;
 
+  if ((MI->getOpcode() == ARM::LDR_POST_IMM || MI->getOpcode() == ARM::LDR_POST_REG) && isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs))
+    return true;
+
   return false;
 }
 
@@ -136,6 +140,49 @@ static void emitSPUpdate(bool isARM, MachineBasicBlock &MBB,
                        MIFlags, Pred, PredReg);
 }
 
+//
+// Functions to emit CFI Instructions.
+//
+
+static void
+emitDefCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
+                 DebugLoc dl, const ARMBaseInstrInfo &TII,
+                 MachineModuleInfo &MMI,
+                 MCSymbol *FrameLabel,
+                 int CfaOffset) {
+  if (!FrameLabel) {
+    FrameLabel = MMI.getContext().CreateTempSymbol();
+    BuildMI(MBB, MBBI, dl, TII.get(ARM::PROLOG_LABEL)).addSym(FrameLabel);
+  }
+  MMI.addFrameInst(MCCFIInstruction::createDefCfaOffset(FrameLabel, -CfaOffset));
+}
+
+static void
+emitDefCfa(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
+           DebugLoc dl, const ARMBaseInstrInfo &TII,
+		   MachineModuleInfo &MMI,
+           int CfaReg, int CfaOffset) {
+  const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
+
+  MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
+  BuildMI(MBB, MBBI, dl, TII.get(ARM::PROLOG_LABEL)).addSym(FrameLabel);
+
+  unsigned DwarfReg = MRI->getDwarfRegNum(CfaReg, true);
+  MMI.addFrameInst(MCCFIInstruction::createDefCfa(FrameLabel, DwarfReg, -CfaOffset));
+}
+
+static void
+emitCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
+              DebugLoc dl, const ARMBaseInstrInfo &TII,
+              MachineModuleInfo &MMI,
+              MCSymbol *FrameLabel,
+              int Reg, int Offset) {
+  const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
+
+  unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
+  MMI.addFrameInst(MCCFIInstruction::createOffset(FrameLabel, DwarfReg, Offset));
+}
+
 void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
   MachineBasicBlock &MBB = MF.front();
   MachineBasicBlock::iterator MBBI = MBB.begin();
@@ -154,6 +201,12 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
   unsigned FramePtr = RegInfo->getFrameRegister(MF);
+  MachineModuleInfo &MMI = MF.getMMI();
+  bool NeedsFrameInfo = MF.getFunction()->needsUnwindTableEntry();
+  // The cfa register
+  int CfaReg = ARM::SP;
+  // The offset between the value of CfaReg and the CFA
+  int CfaOffset = 0;
 
   // Determine the sizes of each callee-save spill areas and record which frame
   // belongs to which callee-save spill areas.
@@ -170,11 +223,15 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
   if (ArgRegsSaveSize)
     emitSPUpdate(isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
                  MachineInstr::FrameSetup);
+  CfaOffset += ArgRegsSaveSize;
 
   if (!AFI->hasStackFrame()) {
     if (NumBytes != 0)
       emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
                    MachineInstr::FrameSetup);
+    CfaOffset += NumBytes;
+    if (NeedsFrameInfo && CfaOffset)
+      emitDefCfaOffset(MBB, MBBI, dl, TII, MMI, NULL, CfaOffset);
     return;
   }
 
@@ -221,6 +278,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
   if (GPRCS1Size > 0)
     FramePtrPush = LastPush = MBBI++;
 
+  CfaOffset += GPRCS1Size;
+
   // Determine starting offsets of spill areas.
   bool HasFP = hasFP(MF);
   unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
@@ -241,6 +300,23 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
     LastPush = MBBI++;
   }
 
+  if (NeedsFrameInfo) {
+    MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
+    BuildMI(MBB, MBBI, dl, TII.get(ARM::PROLOG_LABEL)).addSym(FrameLabel);
+
+    // Emit moves for the registers in spill area 2
+    for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+      unsigned Reg = CSI[i].getReg();
+      int FI = CSI[i].getFrameIdx();
+      int64_t Offset = MFI->getObjectOffset(FI);
+
+      // The offset is relative to the incoming stack pointer which is
+      // the cfa
+	  // Reg is saved at cfa + offset
+	  emitCfaOffset(MBB, MBBI, dl, TII, MMI, FrameLabel, Reg, Offset);
+    }
+  }
+
   // Move past area 3.
   if (DPRCSSize > 0) {
     LastPush = MBBI++;
@@ -279,6 +355,11 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
       // an inconsistent state (pointing to the middle of callee-saved area).
       // The interrupt handler can end up clobbering the registers.
       AFI->setShouldRestoreSPFromFP(true);
+
+    if (NeedsFrameInfo && CfaReg == ARM::SP) {
+      CfaOffset += NumBytes;
+      emitDefCfaOffset(MBB, MBBI, dl, TII, MMI, NULL, CfaOffset);
+    }
   }
 
   // Set FP to point to the stack slot that contains the previous FP.
@@ -287,11 +368,18 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
   // into spill area 1, including the FP in R11.  In either case, it
   // is in area one and the adjustment needs to take place just after
   // that push.
-  if (HasFP)
+  if (HasFP) {
     emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, ++FramePtrPush, dl, TII,
                          FramePtr, ARM::SP, FramePtrOffsetInPush,
                          MachineInstr::FrameSetup);
 
+    if (NeedsFrameInfo) {
+      // CFA = FramePtr + offset from cfa where fp was stored
+      CfaReg = FramePtr;
+      CfaOffset = MFI->getObjectOffset (FramePtrSpillFI);
+      emitDefCfa(MBB, MBBI, dl, TII, MMI, CfaReg, CfaOffset);
+    }
+  }
 
   if (STI.isTargetELF() && hasFP(MF))
     MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
@@ -441,8 +529,9 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
                                  ARM::SP)
             .addReg(FramePtr));
       }
-    } else if (NumBytes && !tryFoldSPUpdateIntoPushPop(MF, FirstPop, NumBytes))
+    } else if (NumBytes && !tryFoldSPUpdateIntoPushPop(MF, FirstPop, NumBytes)) {
         emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
+    }
 
     // Increment past our save areas.
     if (AFI->getDPRCalleeSavedAreaSize()) {

Modified: lib/Target/ARM/Thumb1FrameLowering.cpp
===================================================================
@@ -17,6 +17,10 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/IR/Function.h"
 
 using namespace llvm;
 
@@ -43,7 +47,6 @@ bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const{
                             MRI, MIFlags);
 }
 
-
 void Thumb1FrameLowering::
 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator I) const {
@@ -78,6 +81,49 @@ bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const{
   MBB.erase(I);
 }
 
+//
+// Functions to emit CFI Instructions.
+//
+
+static void
+emitDefCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
+                 DebugLoc dl, const ARMBaseInstrInfo &TII,
+                 MachineModuleInfo &MMI,
+                 MCSymbol *FrameLabel,
+                 int CfaOffset) {
+  if (!FrameLabel) {
+    FrameLabel = MMI.getContext().CreateTempSymbol();
+    BuildMI(MBB, MBBI, dl, TII.get(ARM::PROLOG_LABEL)).addSym(FrameLabel);
+  }
+  MMI.addFrameInst(MCCFIInstruction::createDefCfaOffset(FrameLabel, CfaOffset));
+}
+
+static void
+emitDefCfa(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
+           DebugLoc dl, const ARMBaseInstrInfo &TII,
+		   MachineModuleInfo &MMI,
+           int CfaReg, int CfaOffset) {
+  const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
+
+  MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
+  BuildMI(MBB, MBBI, dl, TII.get(ARM::PROLOG_LABEL)).addSym(FrameLabel);
+
+  unsigned DwarfReg = MRI->getDwarfRegNum(CfaReg, true);
+  MMI.addFrameInst(MCCFIInstruction::createDefCfa(FrameLabel, DwarfReg, CfaOffset));
+}
+
+static void
+emitCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
+              DebugLoc dl, const ARMBaseInstrInfo &TII,
+              MachineModuleInfo &MMI,
+              MCSymbol *FrameLabel,
+              int Reg, int Offset) {
+  const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
+
+  unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
+  MMI.addFrameInst(MCCFIInstruction::createOffset(FrameLabel, DwarfReg, Offset));
+}
+
 void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
   MachineBasicBlock &MBB = MF.front();
   MachineBasicBlock::iterator MBBI = MBB.begin();
@@ -95,6 +141,12 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
   unsigned FramePtr = RegInfo->getFrameRegister(MF);
   unsigned BasePtr = RegInfo->getBaseRegister();
+  MachineModuleInfo &MMI = MF.getMMI();
+  bool NeedsFrameMoves = MF.getFunction()->needsUnwindTableEntry();
+  // The cfa register
+  int CfaReg = ARM::SP;
+  // The offset between the value of CfaReg and the CFA
+  int CfaOffset = 0;
 
   // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
   NumBytes = (NumBytes + 3) & ~3;
@@ -108,11 +160,15 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
   if (ArgRegsSaveSize)
     emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -ArgRegsSaveSize,
                  MachineInstr::FrameSetup);
+  CfaOffset += ArgRegsSaveSize;
 
   if (!AFI->hasStackFrame()) {
     if (NumBytes != 0)
       emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
                    MachineInstr::FrameSetup);
+    CfaOffset += NumBytes;
+    if (NeedsFrameMoves && CfaOffset)
+      emitDefCfaOffset(MBB, MBBI, dl, TII, MMI, NULL, CfaOffset);
     return;
   }
 
@@ -151,6 +207,26 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
       dl = MBBI->getDebugLoc();
   }
 
+  CfaOffset += GPRCS1Size;
+  if (NeedsFrameMoves) {
+    MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
+    BuildMI(MBB, MBBI, dl, TII.get(ARM::PROLOG_LABEL)).addSym(FrameLabel);
+    // CFA = sp + offset
+    emitDefCfaOffset(MBB, MBBI, dl, TII, MMI, FrameLabel, CfaOffset);
+
+    // Emit moves for the registers in spill area 1
+    for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+      unsigned Reg = CSI[i].getReg();
+      int FI = CSI[i].getFrameIdx();
+      int64_t Offset = MFI->getObjectOffset(FI);
+
+      // The offset is relative to the incoming stack pointer which is
+      // the cfa
+	  // Reg is saved at cfa + offset
+	  emitCfaOffset(MBB, MBBI, dl, TII, MMI, FrameLabel, Reg, Offset);
+    }
+  }
+
   // Determine starting offsets of spill areas.
   unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
   unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
@@ -180,13 +256,26 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
       // If offset is > 508 then sp cannot be adjusted in a single instruction,
       // try restoring from fp instead.
       AFI->setShouldRestoreSPFromFP(true);
+
+    if (NeedsFrameMoves) {
+      // CFA = FramePtr + offset from cfa where fp was stored
+      CfaReg = FramePtr;
+      CfaOffset = MFI->getObjectOffset (FramePtrSpillFI);
+      emitDefCfa(MBB, MBBI, dl, TII, MMI, CfaReg, CfaOffset);
+    }
   }
 
-  if (NumBytes)
+  if (NumBytes) {
     // Insert it after all the callee-save spills.
     emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
                  MachineInstr::FrameSetup);
 
+    if (NeedsFrameMoves && CfaReg == ARM::SP) {
+      CfaOffset += NumBytes;
+      emitDefCfaOffset(MBB, MBBI, dl, TII, MMI, NULL, CfaOffset);
+    }
+  }
+
   if (STI.isTargetELF() && HasFP)
     MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
                              AFI->getFramePtrSpillOffset());

   Commit: 70f31ddf5041825e896994d272ffe5da4fa3add4
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-16 13:25:26 GMT
      URL: https://github.com/mono/llvm/commit/70f31ddf5041825e896994d272ffe5da4fa3add4

Use DWARF EH on ARM.

Changed paths:
  M lib/Target/ARM/ARMISelLowering.cpp
  M lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
  M lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp

Modified: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
@@ -733,7 +733,8 @@ static TargetLoweringObjectFile *createTLOF(TargetMachine &TM) {
   setOperationAction(ISD::STACKSAVE,          MVT::Other, Expand);
   setOperationAction(ISD::STACKRESTORE,       MVT::Other, Expand);
 
-  if (!Subtarget->isTargetDarwin()) {
+  // Mono uses dwarf EH on darwin as well
+  if (true) { //if (!Subtarget->isTargetDarwin()) {
     // Non-Darwin platforms may return values in these registers via the
     // personality function.
     setExceptionPointerRegister(ARM::R0);

Modified: lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
===================================================================
@@ -33,8 +33,8 @@ void ARMMCAsmInfoDarwin::anchor() { }
 
   SupportsDebugInformation = true;
 
-  // Exceptions handling
-  ExceptionsType = ExceptionHandling::SjLj;
+  // Mono uses a variant of Dwarf CFI
+  ExceptionsType = ExceptionHandling::DwarfCFI;
 }
 
 void ARMELFMCAsmInfo::anchor() { }
@@ -53,6 +53,10 @@ void ARMELFMCAsmInfo::anchor() { }
   SupportsDebugInformation = true;
 
   // Exceptions handling
+  // Mono uses a variant of Dwarf CFI
+  ExceptionsType = ExceptionHandling::DwarfCFI;
+#if 0
   if (EnableARMEHABI)
     ExceptionsType = ExceptionHandling::ARM;
+#endif
 }

Modified: lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
===================================================================
@@ -214,11 +214,20 @@ static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) {
 
 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
   Triple TheTriple(TT);
+  MCAsmInfo *MAI;
 
   if (TheTriple.isOSDarwin())
-    return new ARMMCAsmInfoDarwin();
+    MAI = new ARMMCAsmInfoDarwin();
+  else
+    MAI = new ARMELFMCAsmInfo();
 
-  return new ARMELFMCAsmInfo();
+  // Initialize initial frame state.
+  // Initial state of the frame pointer is sp
+  MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(
+      0, MRI.getDwarfRegNum(ARM::SP, true), 0);
+  MAI->addInitialFrameState(Inst);
+
+  return MAI;
 }
 
 static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM,


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches