[mono/llvm] [17 commits] 9427faa4: Add x86.sse2.pause intrinsic.

"Zoltan Varga ([email protected])" <[email protected]> Sat, 16 Nov 2013 07:59:01 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <000001425feb8aef-da9e791e-2ad9-4c7e-b685-20fa1ee5cb21-000000@email.amazonses.com>
   Branch: refs/heads/mono3
     Home: https://github.com/mono/llvm
  Compare: https://github.com/mono/llvm/compare/9427faa49c2e^...f9b1a74368ec

   Commit: 9427faa49c2e91488ead41e528c66a0039314921
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:18:12 GMT
      URL: https://github.com/mono/llvm/commit/9427faa49c2e91488ead41e528c66a0039314921

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: 60e648a27fae1d8ff0ecee8d68a5064df39a2fc6
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:18:18 GMT
      URL: https://github.com/mono/llvm/commit/60e648a27fae1d8ff0ecee8d68a5064df39a2fc6

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: d8c5aaad3254a2d69930ee98cd92a615d497ce8d
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:18:23 GMT
      URL: https://github.com/mono/llvm/commit/d8c5aaad3254a2d69930ee98cd92a615d497ce8d

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: be8ce94fcb31b942cd2ab9ed58dd5dbb540fe28a
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:18:29 GMT
      URL: https://github.com/mono/llvm/commit/be8ce94fcb31b942cd2ab9ed58dd5dbb540fe28a

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: 2abf9d476b70a759942aa8ef5f25fdc451d91d20
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:18:36 GMT
      URL: https://github.com/mono/llvm/commit/2abf9d476b70a759942aa8ef5f25fdc451d91d20

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: 6a439b33b7f9da82990609913cddf77e21c1b2a4
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:19:54 GMT
      URL: https://github.com/mono/llvm/commit/6a439b33b7f9da82990609913cddf77e21c1b2a4

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: 5896c0814e34a750c94b73f7c097275431af1b8b
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:20:02 GMT
      URL: https://github.com/mono/llvm/commit/5896c0814e34a750c94b73f7c097275431af1b8b

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: 1bbf772eaf9c3490fc59b29c5ecf41bb00ce9c04
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:20:12 GMT
      URL: https://github.com/mono/llvm/commit/1bbf772eaf9c3490fc59b29c5ecf41bb00ce9c04

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: 49bbca3c352cc4f7d77c61371369a23354c8975f
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:20:21 GMT
      URL: https://github.com/mono/llvm/commit/49bbca3c352cc4f7d77c61371369a23354c8975f

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: 9fdaef73772657196a954290ee6dfb52c929eac5
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:20:33 GMT
      URL: https://github.com/mono/llvm/commit/9fdaef73772657196a954290ee6dfb52c929eac5

Add back the JIT dwarf emission functionality removed by r181354 and r181649.

Changed paths:
  M include/llvm/ExecutionEngine/ExecutionEngine.h
  M include/llvm/ExecutionEngine/JITMemoryManager.h
  M include/llvm/Target/TargetOptions.h
  M lib/ExecutionEngine/ExecutionEngine.cpp
  M lib/ExecutionEngine/JIT/CMakeLists.txt
  M lib/ExecutionEngine/JIT/JITEmitter.cpp
  M lib/ExecutionEngine/JIT/JITMemoryManager.cpp
  M tools/lli/RemoteMemoryManager.h
  M unittests/ExecutionEngine/JIT/JITTest.cpp
Added paths:
  A lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
  A lib/ExecutionEngine/JIT/JITDwarfEmitter.h

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/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/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
   )

Added: lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
===================================================================
@@ -0,0 +1,590 @@
+//===----- 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/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/ErrorHandling.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 = EmitExceptionTable(&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");
+    }
+  }
+}
+
+/// SharedTypeIds - How many leading type ids two landing pads have in common.
+static unsigned SharedTypeIds(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;
+  unsigned Count = 0;
+
+  for (; Count != MinSize; ++Count)
+    if (LIds[Count] != RIds[Count])
+      return Count;
+
+  return Count;
+}
+
+
+/// 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 {
+
+/// ActionEntry - Structure describing an entry in the actions table.
+struct ActionEntry {
+  int ValueForTypeID; // The value to write - may not be equal to the type id.
+  int NextAction;
+  struct ActionEntry *Previous;
+};
+
+/// 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.
+  unsigned Action;
+};
+
+}
+
+unsigned char* JITDwarfEmitter::EmitExceptionTable(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<unsigned> &FilterIds = MMI->getFilterIds();
+  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
+  if (PadInfos.empty()) 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);
+
+  // Negative type ids index into FilterIds, positive type ids index into
+  // TypeInfos.  The value written for a positive type id is just the type
+  // id itself.  For a negative type id, however, the value written is the
+  // (negative) byte offset of the corresponding FilterIds entry.  The byte
+  // offset is usually equal to the type id, because the FilterIds entries
+  // are written using a variable width encoding which outputs one byte per
+  // entry as long as the value written is not too large, but can differ.
+  // This kind of complication does not occur for positive type ids because
+  // type infos are output using a fixed width encoding.
+  // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
+  SmallVector<int, 16> FilterOffsets;
+  FilterOffsets.reserve(FilterIds.size());
+  int Offset = -1;
+  for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
+    E = FilterIds.end(); I != E; ++I) {
+    FilterOffsets.push_back(Offset);
+    Offset -= MCAsmInfo::getULEB128Size(*I);
+  }
+
+  // Compute the actions table and gather the first action index for each
+  // landing pad site.
+  SmallVector<ActionEntry, 32> Actions;
+  SmallVector<unsigned, 64> FirstActions;
+  FirstActions.reserve(LandingPads.size());
+
+  int FirstAction = 0;
+  unsigned SizeActions = 0;
+  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
+    const LandingPadInfo *LP = LandingPads[i];
+    const std::vector<int> &TypeIds = LP->TypeIds;
+    const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
+    unsigned SizeSiteActions = 0;
+
+    if (NumShared < TypeIds.size()) {
+      unsigned SizeAction = 0;
+      ActionEntry *PrevAction = 0;
+
+      if (NumShared) {
+        const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
+        assert(Actions.size());
+        PrevAction = &Actions.back();
+        SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) +
+          MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
+        for (unsigned j = NumShared; j != SizePrevIds; ++j) {
+          SizeAction -= MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
+          SizeAction += -PrevAction->NextAction;
+          PrevAction = PrevAction->Previous;
+        }
+      }
+
+      // Compute the actions.
+      for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
+        int TypeID = TypeIds[I];
+        assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
+        int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
+        unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID);
+
+        int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
+        SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction);
+        SizeSiteActions += SizeAction;
+
+        ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
+        Actions.push_back(Action);
+
+        PrevAction = &Actions.back();
+      }
+
+      // Record the first action of the landing pad site.
+      FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
+    } // else identical - re-use previous FirstAction
+
+    FirstActions.push_back(FirstAction);
+
+    // Compute this sites contribution to size.
+    SizeActions += SizeSiteActions;
+  }
+
+  // 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;
+    }
+  }
+
+  bool MayThrow = false;
+  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()) {
+        MayThrow |= MI->isCall();
+        continue;
+      }
+
+      MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol();
+      assert(BeginLabel && "Invalid label!");
+
+      if (BeginLabel == LastLabel)
+        MayThrow = false;
+
+      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!");
+
+      // If some instruction between the previous try-range and this one may
+      // throw, create a call-site entry with no landing pad for the region
+      // between the try-ranges.
+      if (MayThrow) {
+        CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
+        CallSites.push_back(Site);
+      }
+
+      LastLabel = LandingPad->EndLabels[P.RangeIndex];
+      CallSiteEntry Site = {BeginLabel, LastLabel,
+        LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
+
+      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.Action == Prev.Action) {
+          // Extend the range of the previous entry.
+          Prev.EndLabel = Site.EndLabel;
+          continue;
+        }
+      }
+
+      // Otherwise, create a new call-site.
+      CallSites.push_back(Site);
+    }
+  }
+  // If some instruction between the previous try-range and the end of the
+  // function may throw, create a call-site entry with no landing pad for the
+  // region following the try-range.
+  if (MayThrow) {
+    CallSiteEntry Site = {LastLabel, 0, 0, 0};
+    CallSites.push_back(Site);
+  }
+
+  // Final tallies.
+  unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
+                                            sizeof(int32_t) + // Site length.
+                                            sizeof(int32_t)); // Landing pad.
+  for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
+    SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action);
+
+  unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
+
+  unsigned TypeOffset = sizeof(int8_t) + // Call site format
+                        // Call-site table length
+                        MCAsmInfo::getULEB128Size(SizeSites) +
+                        SizeSites + SizeActions + SizeTypes;
+
+  // Begin the exception table.
+  JCE->emitAlignmentWithFill(4, 0);
+  // Asm->EOL("Padding");
+
+  unsigned char* DwarfExceptionTable = (unsigned char*)JCE->getCurrentPCValue();
+
+  // Emit the header.
+  JCE->emitByte(dwarf::DW_EH_PE_omit);
+  // Asm->EOL("LPStart format (DW_EH_PE_omit)");
+  JCE->emitByte(dwarf::DW_EH_PE_absptr);
+  // Asm->EOL("TType format (DW_EH_PE_absptr)");
+  JCE->emitULEB128Bytes(TypeOffset);
+  // Asm->EOL("TType base offset");
+  JCE->emitByte(dwarf::DW_EH_PE_udata4);
+  // Asm->EOL("Call site format (DW_EH_PE_udata4)");
+  JCE->emitULEB128Bytes(SizeSites);
+  // Asm->EOL("Call-site table length");
+
+  // 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);
+    }
+
+    // Asm->EOL("Region start");
+
+    if (!S.EndLabel)
+      EndLabelPtr = (intptr_t)EndFunction;
+    else
+      EndLabelPtr = JCE->getLabelAddress(S.EndLabel);
+
+    JCE->emitInt32(EndLabelPtr - BeginLabelPtr);
+    //Asm->EOL("Region length");
+
+    if (!S.PadLabel) {
+      JCE->emitInt32(0);
+    } else {
+      unsigned PadLabelPtr = JCE->getLabelAddress(S.PadLabel);
+      JCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
+    }
+    // Asm->EOL("Landing pad");
+
+    JCE->emitULEB128Bytes(S.Action);
+    // Asm->EOL("Action");
+  }
+
+  // Emit the actions.
+  for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
+    ActionEntry &Action = Actions[I];
+
+    JCE->emitSLEB128Bytes(Action.ValueForTypeID);
+    //Asm->EOL("TypeInfo index");
+    JCE->emitSLEB128Bytes(Action.NextAction);
+    //Asm->EOL("Next action");
+  }
+
+  // Emit the type ids.
+  for (unsigned M = TypeInfos.size(); M; --M) {
+    const GlobalVariable *GV = TypeInfos[M - 1];
+
+    if (GV) {
+      if (TD->getPointerSize() == sizeof(int32_t))
+        JCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
+      else
+        JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
+    } else {
+      if (TD->getPointerSize() == sizeof(int32_t))
+        JCE->emitInt32(0);
+      else
+        JCE->emitInt64(0);
+    }
+    // Asm->EOL("TypeInfo");
+  }
+
+  // Emit the filter typeids.
+  for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
+    unsigned TypeID = FilterIds[j];
+    JCE->emitULEB128Bytes(TypeID);
+    //Asm->EOL("Filter TypeInfo index");
+  }
+
+  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 (Personality) {
+    JCE->emitULEB128Bytes(PointerSize == 4 ? 4 : 8);
+
+    if (PointerSize == 4) {
+      if (!MMI->getLandingPads().empty())
+        JCE->emitInt32(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
+      else
+        JCE->emitInt32((int)0);
+    } else {
+      if (!MMI->getLandingPads().empty())
+        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* EmitExceptionTable(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: 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: c5fb410109837424364cf7054f54caf3000e4001
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:21:29 GMT
      URL: https://github.com/mono/llvm/commit/c5fb410109837424364cf7054f54caf3000e4001

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.

Changed paths:
  M include/llvm/CodeGen/MachineFunction.h
  M include/llvm/MC/MCObjectFileInfo.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/JIT/JITDwarfEmitter.cpp
  M lib/MC/MCObjectFileInfo.cpp
  M lib/Transforms/Scalar/GlobalMerge.cpp
Added paths:
  A include/llvm/CodeGen/MonoMachineFunctionInfo.h
  A lib/CodeGen/AsmPrinter/DwarfMonoException.cpp

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/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: 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,45 @@ class DwarfException {
     unsigned Previous;
   };
 
-  /// 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.
+  // Mono specific
+  struct MonoEHFrameInfo {
+    const MachineFunction *MF;
+    std::vector<CallSiteEntry> CallSites;
+    std::vector<const GlobalVariable *> TypeInfos;
+    std::vector<unsigned> FilterIds;
+    std::vector<LandingPadInfo> PadInfos;
+    int FunctionNumber;
+    int MonoMethodIdx;
+    int FrameReg;
+    int ThisOffset;
+  };
 
-    // The landing pad starts at PadLabel.
-    MCSymbol *PadLabel;   // zero indicates that there is no landing pad.
-    unsigned Action;
+  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 +272,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,753 @@
+//===-- 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
+      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());
+
+    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<unsigned> &FilterIds = MMI->getFilterIds();
+  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
+
+  // 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 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);
+
+  // 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<CallSiteEntry, 64> CallSites;
+  ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions);
+
+  //
+  // 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->FilterIds = FilterIds;
+  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
+///
+///   We emit the information inline instead of into a separate section.
+///
+void DwarfMonoException::EmitMonoLSDA(const FunctionEHFrameInfo *EFI) {
+  //
+  // The code below is a modified/simplified version of EmitExceptionTable
+  //
+
+  // Load saved information from EHFrameInfo
+  const MonoEHFrameInfo *MonoEH = &EFI->MonoEH;
+  const std::vector<const GlobalVariable *> &TypeInfos = MonoEH->TypeInfos;
+  const std::vector<unsigned> &FilterIds = MonoEH->FilterIds;
+  const std::vector<LandingPadInfo> &PadInfos = MonoEH->PadInfos;
+  const std::vector<CallSiteEntry> 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);
+
+  // Compute the actions table and gather the first action index for each
+  // landing pad site.
+  SmallVector<ActionEntry, 32> Actions;
+  SmallVector<unsigned, 64> FirstActions;
+  unsigned SizeActions=ComputeActionsTable(LandingPads, Actions, FirstActions);
+
+  // 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);
+
+  // Final tallies.
+
+  // Call sites.
+  
+  unsigned CallSiteTableLength;
+
+  unsigned SiteStartSize  = 4; // dwarf::DW_EH_PE_udata4
+  unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4
+  unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4
+  CallSiteTableLength = 
+    CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize);
+
+  for (unsigned i = 0, e = CallSites.size(); i < e; ++i) {
+    CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action);
+  }
+
+  // Type infos.
+  unsigned TTypeEncoding;
+  unsigned TypeFormatSize;
+
+  // The type_info itself is emitted
+  TTypeEncoding = dwarf::DW_EH_PE_udata4;
+  TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding);
+
+  // Emit the LSDA.
+
+  // Emit the LSDA header.
+  if (FrameReg != -1) {
+    // Keep this in sync with JITDwarfEmitter::EmitExceptionTable ()
+    // FIXME: If this method has no clauses, avoid emitting the rest of the info
+    // Mark that this is a mono specific LSDA header using a magic value
+    Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "@LPStart");
+    Asm->EmitULEB128(0x4d4fef4f, "MONO Magic", 0);
+    Asm->EmitULEB128(1, "Version", 0);
+
+    // 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, "@LPStart");
+  }
+  Asm->EmitEncodingByte(TTypeEncoding, "@TType");
+
+  unsigned SizeTypes = TypeInfos.size() * TypeFormatSize;
+  unsigned CallSiteTableLengthSize =
+    MCAsmInfo::getULEB128Size(CallSiteTableLength);
+  unsigned TTypeBaseOffset =
+    sizeof(int8_t) +                            // Call site format
+    CallSiteTableLengthSize +                   // Call site table length size
+    CallSiteTableLength +                       // Call site table length
+    SizeActions +                               // Actions size
+    SizeTypes;
+
+  Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", 0);
+
+  assert(Asm->MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI);
+
+  // The call-site table is a list of all call sites that may throw an
+  // exception (including C++ 'throw' statements) in the procedure
+  // fragment. It immediately follows the LSDA header. Each entry indicates,
+  // for a given call, the first corresponding action record and corresponding
+  // landing pad.
+  //
+  // The table begins with the number of bytes, stored as an LEB128
+  // compressed, unsigned integer. The records immediately follow the record
+  // count. They are sorted in increasing call-site address. Each record
+  // indicates:
+  //
+  //   * The position of the call-site.
+  //   * The position of the landing pad.
+  //   * The first action record for that call site.
+  //
+  // A missing entry in the call-site table indicates that a call is not
+  // supposed to throw.
+
+  // Emit the landing pad call site table.
+  Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
+
+  // Add extra padding if it wasn't added to the TType base offset.
+  Asm->EmitULEB128(CallSiteTableLength, "Call site table length", 0);
+
+  for (std::vector<CallSiteEntry>::const_iterator
+         I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
+    const CallSiteEntry &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);
+        
+    // Offset of the call site relative to the previous call site, counted in
+    // number of 16-byte bundles. The first call site is counted relative to
+    // the start of the procedure fragment.
+    Asm->OutStreamer.AddComment("Region start");
+    Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4);
+      
+    Asm->OutStreamer.AddComment("Region length");
+    Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
+
+
+    // Offset of the landing pad, counted in 16-byte bundles relative to the
+    // @LPStart address.
+    Asm->OutStreamer.AddComment("Landing pad");
+    if (!S.PadLabel)
+      Asm->OutStreamer.EmitIntValue(0, 4/*size*/);
+    else
+      Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4);
+
+    // Offset of the first associated action record, relative to the start of
+    // the action table. This value is biased by 1 (1 indicates the start of
+    // the action table), and 0 indicates that there are no actions.
+    Asm->EmitULEB128(S.Action, "Action");
+  }
+
+  // Emit the Action Table.
+  if (Actions.size() != 0) {
+    Asm->OutStreamer.AddComment("-- Action Record Table --");
+    Asm->OutStreamer.AddBlankLine();
+  }
+  
+  for (SmallVectorImpl<ActionEntry>::const_iterator
+         I = Actions.begin(), E = Actions.end(); I != E; ++I) {
+    const ActionEntry &Action = *I;
+    Asm->OutStreamer.AddComment("Action Record");
+    Asm->OutStreamer.AddBlankLine();
+
+    // Type Filter
+    //
+    //   Used by the runtime to match the type of the thrown exception to the
+    //   type of the catch clauses or the types in the exception specification.
+    Asm->EmitSLEB128(Action.ValueForTypeID, "  TypeInfo index");
+
+    // Action Record
+    //
+    //   Self-relative signed displacement in bytes of the next action record,
+    //   or 0 if there is no next action record.
+    Asm->EmitSLEB128(Action.NextAction, "  Next action");
+  }
+
+  // Emit the Catch TypeInfos.
+  if (!TypeInfos.empty()) {
+    Asm->OutStreamer.AddComment("-- Catch TypeInfos --");
+    Asm->OutStreamer.AddBlankLine();
+  }
+  for (std::vector<const GlobalVariable *>::const_reverse_iterator
+         I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
+    const GlobalVariable *GV = *I;
+
+    //
+    // 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));
+  }
+
+  // Emit the Exception Specifications.
+  if (!FilterIds.empty()) {
+    Asm->OutStreamer.AddComment("-- Filter IDs --");
+    Asm->OutStreamer.AddBlankLine();
+  }
+  for (std::vector<unsigned>::const_iterator
+         I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
+    unsigned TypeID = *I;
+    Asm->EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0);
+  }
+}
+
+// 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/JIT/JITDwarfEmitter.cpp
===================================================================
@@ -18,13 +18,16 @@
 #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"
@@ -201,7 +204,10 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
   const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
-  if (PadInfos.empty()) return 0;
+
+  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.
@@ -388,8 +394,25 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
   unsigned char* DwarfExceptionTable = (unsigned char*)JCE->getCurrentPCValue();
 
   // Emit the header.
-  JCE->emitByte(dwarf::DW_EH_PE_omit);
-  // Asm->EOL("LPStart format (DW_EH_PE_omit)");
+
+  if (ThisSlot != -1) {
+    // Keep this in sync with DwarfException::EmitExceptionTable ()
+    JCE->emitByte(dwarf::DW_EH_PE_udata4);
+    JCE->emitULEB128Bytes(0x4d4fef4f);
+    JCE->emitULEB128Bytes(1);
+
+    // Emit 'this' location
+    unsigned FrameReg;
+    int Offset = MF->getTarget ().getFrameLowering ()->getFrameIndexReference (*MF, ThisSlot, FrameReg);
+    FrameReg = MF->getTarget ().getRegisterInfo ()->getDwarfRegNum (FrameReg, true);
+
+    JCE->emitByte((int)dwarf::DW_OP_bregx);
+    JCE->emitULEB128Bytes(FrameReg);
+    JCE->emitSLEB128Bytes(Offset);
+  } else {
+    JCE->emitByte(dwarf::DW_EH_PE_omit);
+    // Asm->EOL("LPStart format (DW_EH_PE_omit)");
+  }
   JCE->emitByte(dwarf::DW_EH_PE_absptr);
   // Asm->EOL("TType format (DW_EH_PE_absptr)");
   JCE->emitULEB128Bytes(TypeOffset);
@@ -550,16 +573,16 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
 
   // If there is a personality and landing pads then point to the language
   // specific data area in the exception table.
-  if (Personality) {
+  if (ExceptionTable) {
     JCE->emitULEB128Bytes(PointerSize == 4 ? 4 : 8);
 
     if (PointerSize == 4) {
-      if (!MMI->getLandingPads().empty())
+      if (ExceptionTable)
         JCE->emitInt32(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
       else
         JCE->emitInt32((int)0);
     } else {
-      if (!MMI->getLandingPads().empty())
+      if (ExceptionTable)
         JCE->emitInt64(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
       else
         JCE->emitInt64((int)0);

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

   Commit: b112d54cb61a8c34214733c4ea55b5057149d7b9
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:21:47 GMT
      URL: https://github.com/mono/llvm/commit/b112d54cb61a8c34214733c4ea55b5057149d7b9

Fix a crash in JIT::getOrEmitGlobalVariable () if the code buffer overflows.

Changed paths:
  M lib/ExecutionEngine/JIT/JIT.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.
   }

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

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: 251d4c7ce928d4894445db2628d3a8544355a033
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:21:59 GMT
      URL: https://github.com/mono/llvm/commit/251d4c7ce928d4894445db2628d3a8544355a033

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: 49d6a5bd87c9a4ced17bbb4a9184a6962ebdd069
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:22:38 GMT
      URL: https://github.com/mono/llvm/commit/49d6a5bd87c9a4ced17bbb4a9184a6962ebdd069

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: 856c118154523627c4a36338b2128c81598c003c
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-15 02:22:53 GMT
      URL: https://github.com/mono/llvm/commit/856c118154523627c4a36338b2128c81598c003c

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,

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

Simplify the mono specific exception tables.

Changed paths:
  M lib/CodeGen/AsmPrinter/DwarfException.h
  M lib/CodeGen/AsmPrinter/DwarfMonoException.cpp
  M lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
  M lib/ExecutionEngine/JIT/JITDwarfEmitter.h

Modified: lib/CodeGen/AsmPrinter/DwarfException.h
===================================================================
@@ -80,10 +80,20 @@ class DwarfException {
     unsigned Previous;
   };
 
+  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.
+	int TypeID;
+  };
+
   // Mono specific
   struct MonoEHFrameInfo {
     const MachineFunction *MF;
-    std::vector<CallSiteEntry> CallSites;
+    std::vector<MonoCallSiteEntry> CallSites;
     std::vector<const GlobalVariable *> TypeInfos;
     std::vector<unsigned> FilterIds;
     std::vector<LandingPadInfo> PadInfos;

Modified: lib/CodeGen/AsmPrinter/DwarfMonoException.cpp
===================================================================
@@ -99,7 +99,9 @@ void EmitCFIInstruction(MCStreamer &Streamer,
     if (IsRelative)
       CFAOffset += Instr.getOffset();
     else
-      CFAOffset = -Instr.getOffset();
+      // The backends pass in a negative value,
+      // then createDefCfaOffset () negates it
+      CFAOffset = Instr.getOffset();
 
     if (VerboseAsm)
       Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
@@ -116,6 +118,8 @@ void EmitCFIInstruction(MCStreamer &Streamer,
       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)
@@ -242,8 +246,8 @@ void EmitCFIInstructions(MCStreamer &streamer,
 ///
 void DwarfMonoException::PrepareMonoLSDA(FunctionEHFrameInfo *EHFrameInfo) {
   const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
-  const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
   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.
@@ -255,11 +259,13 @@ void DwarfMonoException::PrepareMonoLSDA(FunctionEHFrameInfo *EHFrameInfo) {
 
   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
@@ -276,8 +282,58 @@ void DwarfMonoException::PrepareMonoLSDA(FunctionEHFrameInfo *EHFrameInfo) {
   }
 
   // Compute the call-site table.
-  SmallVector<CallSiteEntry, 64> CallSites;
-  ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions);
+  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
@@ -302,7 +358,6 @@ void DwarfMonoException::PrepareMonoLSDA(FunctionEHFrameInfo *EHFrameInfo) {
   MonoEH->FunctionNumber = Asm->getFunctionNumber();
   MonoEH->CallSites.insert(MonoEH->CallSites.begin(), CallSites.begin(), CallSites.end());
   MonoEH->TypeInfos = TypeInfos;
-  MonoEH->FilterIds = FilterIds;
   MonoEH->PadInfos = PadInfos;
   MonoEH->MonoMethodIdx = FuncIndexes.lookup (Asm->MF->getFunction ()->getName ()) - 1;
   //outs()<<"A:"<<Asm->MF->getFunction()->getName() << " " << MonoEH->MonoMethodIdx << "\n";
@@ -320,19 +375,15 @@ void DwarfMonoException::PrepareMonoLSDA(FunctionEHFrameInfo *EHFrameInfo) {
 
 /// EmitMonoLSDA - Mono's version of EmitExceptionTable
 ///
-///   We emit the information inline instead of into a separate section.
+/// 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) {
-  //
-  // The code below is a modified/simplified version of EmitExceptionTable
-  //
-
   // Load saved information from EHFrameInfo
   const MonoEHFrameInfo *MonoEH = &EFI->MonoEH;
   const std::vector<const GlobalVariable *> &TypeInfos = MonoEH->TypeInfos;
-  const std::vector<unsigned> &FilterIds = MonoEH->FilterIds;
   const std::vector<LandingPadInfo> &PadInfos = MonoEH->PadInfos;
-  const std::vector<CallSiteEntry> CallSites = MonoEH->CallSites;
+  const std::vector<MonoCallSiteEntry> CallSites = MonoEH->CallSites;
   int FunctionNumber = MonoEH->FunctionNumber;
   int FrameReg = MonoEH->FrameReg;
   int ThisOffset = MonoEH->ThisOffset;
@@ -347,12 +398,6 @@ void DwarfMonoException::EmitMonoLSDA(const FunctionEHFrameInfo *EFI) {
 
   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
 
-  // Compute the actions table and gather the first action index for each
-  // landing pad site.
-  SmallVector<ActionEntry, 32> Actions;
-  SmallVector<unsigned, 64> FirstActions;
-  unsigned SizeActions=ComputeActionsTable(LandingPads, Actions, FirstActions);
-
   // 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.
@@ -369,40 +414,17 @@ void DwarfMonoException::EmitMonoLSDA(const FunctionEHFrameInfo *EFI) {
 
   assert(Asm->MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI);
 
-  // Final tallies.
-
-  // Call sites.
-  
-  unsigned CallSiteTableLength;
-
-  unsigned SiteStartSize  = 4; // dwarf::DW_EH_PE_udata4
-  unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4
-  unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4
-  CallSiteTableLength = 
-    CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize);
-
-  for (unsigned i = 0, e = CallSites.size(); i < e; ++i) {
-    CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action);
-  }
-
-  // Type infos.
-  unsigned TTypeEncoding;
-  unsigned TypeFormatSize;
-
   // The type_info itself is emitted
-  TTypeEncoding = dwarf::DW_EH_PE_udata4;
-  TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding);
+  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) {
-    // Keep this in sync with JITDwarfEmitter::EmitExceptionTable ()
-    // FIXME: If this method has no clauses, avoid emitting the rest of the info
-    // Mark that this is a mono specific LSDA header using a magic value
-    Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "@LPStart");
-    Asm->EmitULEB128(0x4d4fef4f, "MONO Magic", 0);
-    Asm->EmitULEB128(1, "Version", 0);
+    Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "This encoding");
 
     // Emit 'this' location
     Asm->OutStreamer.AddComment("bregx");
@@ -410,51 +432,14 @@ void DwarfMonoException::EmitMonoLSDA(const FunctionEHFrameInfo *EFI) {
     Asm->EmitULEB128(FrameReg, "Base reg");
     Asm->EmitSLEB128(ThisOffset, "Offset");
   } else {
-    Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
+    Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@This encoding");
   }
-  Asm->EmitEncodingByte(TTypeEncoding, "@TType");
-
-  unsigned SizeTypes = TypeInfos.size() * TypeFormatSize;
-  unsigned CallSiteTableLengthSize =
-    MCAsmInfo::getULEB128Size(CallSiteTableLength);
-  unsigned TTypeBaseOffset =
-    sizeof(int8_t) +                            // Call site format
-    CallSiteTableLengthSize +                   // Call site table length size
-    CallSiteTableLength +                       // Call site table length
-    SizeActions +                               // Actions size
-    SizeTypes;
-
-  Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", 0);
 
-  assert(Asm->MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI);
-
-  // The call-site table is a list of all call sites that may throw an
-  // exception (including C++ 'throw' statements) in the procedure
-  // fragment. It immediately follows the LSDA header. Each entry indicates,
-  // for a given call, the first corresponding action record and corresponding
-  // landing pad.
-  //
-  // The table begins with the number of bytes, stored as an LEB128
-  // compressed, unsigned integer. The records immediately follow the record
-  // count. They are sorted in increasing call-site address. Each record
-  // indicates:
-  //
-  //   * The position of the call-site.
-  //   * The position of the landing pad.
-  //   * The first action record for that call site.
-  //
-  // A missing entry in the call-site table indicates that a call is not
-  // supposed to throw.
-
-  // Emit the landing pad call site table.
-  Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
-
-  // Add extra padding if it wasn't added to the TType base offset.
-  Asm->EmitULEB128(CallSiteTableLength, "Call site table length", 0);
-
-  for (std::vector<CallSiteEntry>::const_iterator
+  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 CallSiteEntry &S = *I;
+    const MonoCallSiteEntry &S = *I;
       
     MCSymbol *EHFuncBeginSym =
       Asm->GetTempSymbol("eh_func_begin", FunctionNumber);
@@ -466,63 +451,22 @@ void DwarfMonoException::EmitMonoLSDA(const FunctionEHFrameInfo *EFI) {
     if (EndLabel == 0)
       EndLabel = Asm->GetTempSymbol("eh_func_end", FunctionNumber);
         
-    // Offset of the call site relative to the previous call site, counted in
-    // number of 16-byte bundles. The first call site is counted relative to
-    // the start of the procedure fragment.
     Asm->OutStreamer.AddComment("Region start");
     Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4);
       
     Asm->OutStreamer.AddComment("Region length");
     Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
 
-
-    // Offset of the landing pad, counted in 16-byte bundles relative to the
-    // @LPStart address.
     Asm->OutStreamer.AddComment("Landing pad");
     if (!S.PadLabel)
-      Asm->OutStreamer.EmitIntValue(0, 4/*size*/);
+      Asm->OutStreamer.EmitIntValue(0, 4);
     else
       Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4);
 
-    // Offset of the first associated action record, relative to the start of
-    // the action table. This value is biased by 1 (1 indicates the start of
-    // the action table), and 0 indicates that there are no actions.
-    Asm->EmitULEB128(S.Action, "Action");
-  }
-
-  // Emit the Action Table.
-  if (Actions.size() != 0) {
-    Asm->OutStreamer.AddComment("-- Action Record Table --");
-    Asm->OutStreamer.AddBlankLine();
-  }
-  
-  for (SmallVectorImpl<ActionEntry>::const_iterator
-         I = Actions.begin(), E = Actions.end(); I != E; ++I) {
-    const ActionEntry &Action = *I;
-    Asm->OutStreamer.AddComment("Action Record");
-    Asm->OutStreamer.AddBlankLine();
-
-    // Type Filter
-    //
-    //   Used by the runtime to match the type of the thrown exception to the
-    //   type of the catch clauses or the types in the exception specification.
-    Asm->EmitSLEB128(Action.ValueForTypeID, "  TypeInfo index");
-
-    // Action Record
-    //
-    //   Self-relative signed displacement in bytes of the next action record,
-    //   or 0 if there is no next action record.
-    Asm->EmitSLEB128(Action.NextAction, "  Next action");
-  }
-
-  // Emit the Catch TypeInfos.
-  if (!TypeInfos.empty()) {
-    Asm->OutStreamer.AddComment("-- Catch TypeInfos --");
-    Asm->OutStreamer.AddBlankLine();
-  }
-  for (std::vector<const GlobalVariable *>::const_reverse_iterator
-         I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
-    const GlobalVariable *GV = *I;
+	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.
@@ -533,17 +477,6 @@ void DwarfMonoException::EmitMonoLSDA(const FunctionEHFrameInfo *EFI) {
     Asm->OutStreamer.AddComment("TypeInfo");
     Asm->OutStreamer.EmitIntValue(ci->getZExtValue(),Asm->GetSizeOfEncodedValue(TTypeEncoding));
   }
-
-  // Emit the Exception Specifications.
-  if (!FilterIds.empty()) {
-    Asm->OutStreamer.AddComment("-- Filter IDs --");
-    Asm->OutStreamer.AddBlankLine();
-  }
-  for (std::vector<unsigned>::const_iterator
-         I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
-    unsigned TypeID = *I;
-    Asm->EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0);
-  }
 }
 
 // EmitMonoEHFrame - Emit Mono specific exception handling tables

Modified: lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
===================================================================
@@ -51,8 +51,8 @@ unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F,
   MAI = TM.getMCAsmInfo();
   JCE = &jce;
 
-  unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
-                                                     EndFunction);
+  unsigned char* ExceptionTable = EmitMonoLSDA(&F, StartFunction,
+                                               EndFunction);
 
   unsigned char* Result = 0;
 
@@ -135,22 +135,6 @@ unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F,
   }
 }
 
-/// SharedTypeIds - How many leading type ids two landing pads have in common.
-static unsigned SharedTypeIds(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;
-  unsigned Count = 0;
-
-  for (; Count != MinSize; ++Count)
-    if (LIds[Count] != RIds[Count])
-      return Count;
-
-  return Count;
-}
-
-
 /// 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;
@@ -166,13 +150,6 @@ static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
 
 namespace {
 
-/// ActionEntry - Structure describing an entry in the actions table.
-struct ActionEntry {
-  int ValueForTypeID; // The value to write - may not be equal to the type id.
-  int NextAction;
-  struct ActionEntry *Previous;
-};
-
 /// PadRange - Structure holding a try-range and the associated landing pad.
 struct PadRange {
   // The index of the landing pad.
@@ -188,26 +165,26 @@ 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.
-  unsigned Action;
+  int TypeID;
 };
 
 }
 
-unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
-                                         unsigned char* StartFunction,
-                                         unsigned char* EndFunction) const {
+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<unsigned> &FilterIds = MMI->getFilterIds();
   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
 
   int ThisSlot = MF->getMonoInfo()->getThisStackSlot();
 
-  if (PadInfos.empty() && ThisSlot == -1) return 0;
+  if (PadInfos.empty() && ThisSlot == -1)
+    return 0;
 
   // Sort the landing pads in order of their type ids.  This is used to fold
   // duplicate actions.
@@ -217,83 +194,6 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
     LandingPads.push_back(&PadInfos[i]);
   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
 
-  // Negative type ids index into FilterIds, positive type ids index into
-  // TypeInfos.  The value written for a positive type id is just the type
-  // id itself.  For a negative type id, however, the value written is the
-  // (negative) byte offset of the corresponding FilterIds entry.  The byte
-  // offset is usually equal to the type id, because the FilterIds entries
-  // are written using a variable width encoding which outputs one byte per
-  // entry as long as the value written is not too large, but can differ.
-  // This kind of complication does not occur for positive type ids because
-  // type infos are output using a fixed width encoding.
-  // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
-  SmallVector<int, 16> FilterOffsets;
-  FilterOffsets.reserve(FilterIds.size());
-  int Offset = -1;
-  for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
-    E = FilterIds.end(); I != E; ++I) {
-    FilterOffsets.push_back(Offset);
-    Offset -= MCAsmInfo::getULEB128Size(*I);
-  }
-
-  // Compute the actions table and gather the first action index for each
-  // landing pad site.
-  SmallVector<ActionEntry, 32> Actions;
-  SmallVector<unsigned, 64> FirstActions;
-  FirstActions.reserve(LandingPads.size());
-
-  int FirstAction = 0;
-  unsigned SizeActions = 0;
-  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
-    const LandingPadInfo *LP = LandingPads[i];
-    const std::vector<int> &TypeIds = LP->TypeIds;
-    const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
-    unsigned SizeSiteActions = 0;
-
-    if (NumShared < TypeIds.size()) {
-      unsigned SizeAction = 0;
-      ActionEntry *PrevAction = 0;
-
-      if (NumShared) {
-        const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
-        assert(Actions.size());
-        PrevAction = &Actions.back();
-        SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) +
-          MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
-        for (unsigned j = NumShared; j != SizePrevIds; ++j) {
-          SizeAction -= MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
-          SizeAction += -PrevAction->NextAction;
-          PrevAction = PrevAction->Previous;
-        }
-      }
-
-      // Compute the actions.
-      for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
-        int TypeID = TypeIds[I];
-        assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
-        int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
-        unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID);
-
-        int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
-        SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction);
-        SizeSiteActions += SizeAction;
-
-        ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
-        Actions.push_back(Action);
-
-        PrevAction = &Actions.back();
-      }
-
-      // Record the first action of the landing pad site.
-      FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
-    } // else identical - re-use previous FirstAction
-
-    FirstActions.push_back(FirstAction);
-
-    // Compute this sites contribution to size.
-    SizeActions += SizeSiteActions;
-  }
-
   // Compute the call-site table.  Entries must be ordered by address.
   SmallVector<CallSiteEntry, 64> CallSites;
 
@@ -308,23 +208,18 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
     }
   }
 
-  bool MayThrow = false;
   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()) {
-        MayThrow |= MI->isCall();
         continue;
       }
 
       MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol();
       assert(BeginLabel && "Invalid label!");
 
-      if (BeginLabel == LastLabel)
-        MayThrow = false;
-
       RangeMapType::iterator L = PadMap.find(BeginLabel);
 
       if (L == PadMap.end())
@@ -336,17 +231,14 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
               "Inconsistent landing pad map!");
 
-      // If some instruction between the previous try-range and this one may
-      // throw, create a call-site entry with no landing pad for the region
-      // between the try-ranges.
-      if (MayThrow) {
-        CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
-        CallSites.push_back(Site);
-      }
+      // 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, FirstActions[P.PadIndex]};
+							LandingPad->LandingPadLabel, LandingPad->TypeIds [0]};
 
       assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
               "Invalid landing pad!");
@@ -354,7 +246,7 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
       // Try to merge with the previous call-site.
       if (CallSites.size()) {
         CallSiteEntry &Prev = CallSites.back();
-        if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
+        if (Site.PadLabel == Prev.PadLabel && Site.TypeID == Prev.TypeID) {
           // Extend the range of the previous entry.
           Prev.EndLabel = Site.EndLabel;
           continue;
@@ -365,62 +257,34 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
       CallSites.push_back(Site);
     }
   }
-  // If some instruction between the previous try-range and the end of the
-  // function may throw, create a call-site entry with no landing pad for the
-  // region following the try-range.
-  if (MayThrow) {
-    CallSiteEntry Site = {LastLabel, 0, 0, 0};
-    CallSites.push_back(Site);
-  }
-
-  // Final tallies.
-  unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
-                                            sizeof(int32_t) + // Site length.
-                                            sizeof(int32_t)); // Landing pad.
-  for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
-    SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action);
-
-  unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
-
-  unsigned TypeOffset = sizeof(int8_t) + // Call site format
-                        // Call-site table length
-                        MCAsmInfo::getULEB128Size(SizeSites) +
-                        SizeSites + SizeActions + SizeTypes;
 
   // Begin the exception table.
   JCE->emitAlignmentWithFill(4, 0);
-  // Asm->EOL("Padding");
 
   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) {
-    // Keep this in sync with DwarfException::EmitExceptionTable ()
-    JCE->emitByte(dwarf::DW_EH_PE_udata4);
-    JCE->emitULEB128Bytes(0x4d4fef4f);
-    JCE->emitULEB128Bytes(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);
-    // Asm->EOL("LPStart format (DW_EH_PE_omit)");
   }
-  JCE->emitByte(dwarf::DW_EH_PE_absptr);
-  // Asm->EOL("TType format (DW_EH_PE_absptr)");
-  JCE->emitULEB128Bytes(TypeOffset);
-  // Asm->EOL("TType base offset");
-  JCE->emitByte(dwarf::DW_EH_PE_udata4);
-  // Asm->EOL("Call site format (DW_EH_PE_udata4)");
-  JCE->emitULEB128Bytes(SizeSites);
-  // Asm->EOL("Call-site table length");
+
+  JCE->emitULEB128Bytes (CallSites.size ());
+  JCE->emitAlignmentWithFill(4, 0);
 
   // Emit the landing pad site information.
   for (unsigned i = 0; i < CallSites.size(); ++i) {
@@ -436,15 +300,12 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
       JCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
     }
 
-    // Asm->EOL("Region start");
-
     if (!S.EndLabel)
       EndLabelPtr = (intptr_t)EndFunction;
     else
       EndLabelPtr = JCE->getLabelAddress(S.EndLabel);
 
     JCE->emitInt32(EndLabelPtr - BeginLabelPtr);
-    //Asm->EOL("Region length");
 
     if (!S.PadLabel) {
       JCE->emitInt32(0);
@@ -452,45 +313,13 @@ unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
       unsigned PadLabelPtr = JCE->getLabelAddress(S.PadLabel);
       JCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
     }
-    // Asm->EOL("Landing pad");
-
-    JCE->emitULEB128Bytes(S.Action);
-    // Asm->EOL("Action");
-  }
-
-  // Emit the actions.
-  for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
-    ActionEntry &Action = Actions[I];
-
-    JCE->emitSLEB128Bytes(Action.ValueForTypeID);
-    //Asm->EOL("TypeInfo index");
-    JCE->emitSLEB128Bytes(Action.NextAction);
-    //Asm->EOL("Next action");
-  }
-
-  // Emit the type ids.
-  for (unsigned M = TypeInfos.size(); M; --M) {
-    const GlobalVariable *GV = TypeInfos[M - 1];
-
-    if (GV) {
-      if (TD->getPointerSize() == sizeof(int32_t))
-        JCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
-      else
-        JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
-    } else {
-      if (TD->getPointerSize() == sizeof(int32_t))
-        JCE->emitInt32(0);
-      else
-        JCE->emitInt64(0);
-    }
-    // Asm->EOL("TypeInfo");
-  }
 
-  // Emit the filter typeids.
-  for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
-    unsigned TypeID = FilterIds[j];
-    JCE->emitULEB128Bytes(TypeID);
-    //Asm->EOL("Filter TypeInfo index");
+	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);

Modified: lib/ExecutionEngine/JIT/JITDwarfEmitter.h
===================================================================
@@ -40,9 +40,9 @@ class JITDwarfEmitter {
   JIT& Jit;
   bool stackGrowthDirection;
 
-  unsigned char* EmitExceptionTable(MachineFunction* MF,
-                                    unsigned char* StartFunction,
-                                    unsigned char* EndFunction) const;
+  unsigned char* EmitMonoLSDA(MachineFunction* MF,
+                              unsigned char* StartFunction,
+                              unsigned char* EndFunction) const;
 
   void EmitCFIInstructions(intptr_t BaseLabelPtr,
                       const std::vector<MCCFIInstruction> &Instructions) const;


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