diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc
index 03ff283..6d4f0dd 100644
--- a/lib/Support/Unix/PathV2.inc
+++ b/lib/Support/Unix/PathV2.inc
@@ -43,6 +43,8 @@
 #include <stdio.h>
 #endif
 
+#include <climits>
+
 using namespace llvm;
 
 namespace {
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 9d7be66..c5a96cc 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -62,6 +62,13 @@ ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
 
 const unsigned*
 ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+  bool ghcCall = false;
+
+  if (MF) {
+    const Function *F = MF->getFunction();
+    ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
+  }
+  
   static const unsigned CalleeSavedRegs[] = {
     ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
     ARM::R7, ARM::R6,  ARM::R5,  ARM::R4,
@@ -81,6 +88,17 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
     ARM::D11, ARM::D10, ARM::D9,  ARM::D8,
     0
   };
+
+  static const unsigned GHCCalleeSavedRegs[] = {
+    ARM::LR, ARM::R11,
+
+    ARM::D15, ARM::D14, ARM::D13, ARM::D12,
+    0
+  };
+
+  if (ghcCall) {
+      return GHCCalleeSavedRegs;
+  }
   return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
 }
 
diff --git a/lib/Target/ARM/ARMCallingConv.td b/lib/Target/ARM/ARMCallingConv.td
index 1e6b95e..00697e3 100644
--- a/lib/Target/ARM/ARMCallingConv.td
+++ b/lib/Target/ARM/ARMCallingConv.td
@@ -110,11 +110,27 @@ def RetCC_ARM_AAPCS_Common : CallingConv<[
   CCIfType<[i64], CCAssignToRegWithShadow<[R0, R2], [R1, R3]>>
 ]>;
 
+//
+// GHC ARM calling convention
+// 
+def ARM_AAPCS_GHC : CallingConv<[
+    // Promote i8/i16 arguments to i32.
+    CCIfType<[i8, i16], CCPromoteToType<i32>>,
+    
+    // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, SpLim, F1, F2, F3, F4, D1, D2
+    CCIfType<[i32], CCAssignToReg<[R4, R5, R6, R7, R8, R9, R10, R11]>>,
+
+    CCIfType<[f32], CCAssignToReg<[S16, S17, S18, S19]>>,
+
+    CCIfType<[f64], CCAssignToReg<[D10, D11]>>
+]>;
+
 //===----------------------------------------------------------------------===//
 // ARM AAPCS (EABI) Calling Convention
 //===----------------------------------------------------------------------===//
 
 def CC_ARM_AAPCS : CallingConv<[
+  CCIfCC<"CallingConv::GHC", CCDelegateTo<ARM_AAPCS_GHC>>,
   // Handle all vector types as either f64 or v2f64.
   CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
   CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
@@ -140,6 +156,7 @@ def RetCC_ARM_AAPCS : CallingConv<[
 //===----------------------------------------------------------------------===//
 
 def CC_ARM_AAPCS_VFP : CallingConv<[
+  CCIfCC<"CallingConv::GHC", CCDelegateTo<ARM_AAPCS_GHC>>,
   // Handle all vector types as either f64 or v2f64.
   CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
   CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 82e37c7..fa4b41d 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -1032,6 +1032,8 @@ CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
     return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
   case CallingConv::ARM_APCS:
     return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
+  case CallingConv::GHC:
+    return ARM_AAPCS_GHC;
   }
 }
 
@@ -1185,6 +1187,8 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
   // Temporarily disable tail calls so things don't break.
   if (!EnableARMTailCalls)
     isTailCall = false;
+  if (CallConv == CallingConv::GHC)
+    isTailCall = true;
   if (isTailCall) {
     // Check if it's really possible to do a tail call.
     isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
@@ -1543,6 +1547,10 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
   CallingConv::ID CallerCC = CallerF->getCallingConv();
   bool CCMatch = CallerCC == CalleeCC;
 
+  // GHC's Calling convention supports tail calls
+  if (CalleeCC == CallingConv::GHC)
+      return true;
+
   // Look for obvious safe cases to perform tail call optimization that do not
   // require ABI changes. This is what gcc calls sibcall.
 
