Skip to content

Commit 3ae900a

Browse files
committed
In LLVM 2.9, the GHC calling convention is only supported on x86-32,
x86-64. We (GHC team) would like this patch included as we've recently added support to GHC for the ARM platform. Patch by David Terei! git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_30@142820 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent f2e6e8e commit 3ae900a

File tree

5 files changed

+50
-1
lines changed

5 files changed

+50
-1
lines changed

lib/Target/ARM/ARMBaseRegisterInfo.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
6363

6464
const unsigned*
6565
ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
66+
bool ghcCall = false;
67+
68+
if (MF) {
69+
const Function *F = MF->getFunction();
70+
ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
71+
}
72+
6673
static const unsigned CalleeSavedRegs[] = {
6774
ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
6875
ARM::R7, ARM::R6, ARM::R5, ARM::R4,
@@ -82,7 +89,13 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
8289
ARM::D11, ARM::D10, ARM::D9, ARM::D8,
8390
0
8491
};
85-
return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
92+
93+
static const unsigned GhcCalleeSavedRegs[] = {
94+
0
95+
};
96+
97+
return ghcCall ? GhcCalleeSavedRegs :
98+
STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
8699
}
87100

88101
BitVector ARMBaseRegisterInfo::

lib/Target/ARM/ARMCallingConv.td

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,25 @@ def RetFastCC_ARM_APCS : CallingConv<[
8282
CCDelegateTo<RetCC_ARM_APCS>
8383
]>;
8484

85+
//===----------------------------------------------------------------------===//
86+
// ARM APCS Calling Convention for GHC
87+
//===----------------------------------------------------------------------===//
88+
89+
def CC_ARM_APCS_GHC : CallingConv<[
90+
// Handle all vector types as either f64 or v2f64.
91+
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
92+
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
93+
94+
CCIfType<[v2f64], CCAssignToReg<[Q4, Q5]>>,
95+
CCIfType<[f64], CCAssignToReg<[D8, D9, D10, D11]>>,
96+
CCIfType<[f32], CCAssignToReg<[S16, S17, S18, S19, S20, S21, S22, S23]>>,
97+
98+
// Promote i8/i16 arguments to i32.
99+
CCIfType<[i8, i16], CCPromoteToType<i32>>,
100+
101+
// Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, SpLim
102+
CCIfType<[i32], CCAssignToReg<[R4, R5, R6, R7, R8, R9, R10, R11]>>
103+
]>;
85104

86105
//===----------------------------------------------------------------------===//
87106
// ARM AAPCS (EABI) Calling Convention, common parts

lib/Target/ARM/ARMFastISel.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,11 @@ CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC, bool Return) {
15481548
return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
15491549
case CallingConv::ARM_APCS:
15501550
return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
1551+
case CallingConv::GHC:
1552+
if (Return)
1553+
llvm_unreachable("Can't return in GHC call convention");
1554+
else
1555+
return CC_ARM_APCS_GHC;
15511556
}
15521557
}
15531558

lib/Target/ARM/ARMFrameLowering.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "ARMBaseInstrInfo.h"
1616
#include "ARMBaseRegisterInfo.h"
1717
#include "ARMMachineFunctionInfo.h"
18+
#include "llvm/CallingConv.h"
19+
#include "llvm/Function.h"
1820
#include "MCTargetDesc/ARMAddressingModes.h"
1921
#include "llvm/CodeGen/MachineFrameInfo.h"
2022
#include "llvm/CodeGen/MachineFunction.h"
@@ -139,6 +141,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
139141
unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
140142
int FramePtrSpillFI = 0;
141143

144+
// All calls are tail calls in GHC calling conv, and functions have no prologue/epilogue.
145+
if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
146+
return;
147+
142148
// Allocate the vararg register save area. This is not counted in NumBytes.
143149
if (VARegSaveSize)
144150
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize,
@@ -326,6 +332,10 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
326332
int NumBytes = (int)MFI->getStackSize();
327333
unsigned FramePtr = RegInfo->getFrameRegister(MF);
328334

335+
// All calls are tail calls in GHC calling conv, and functions have no prologue/epilogue.
336+
if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
337+
return;
338+
329339
if (!AFI->hasStackFrame()) {
330340
if (NumBytes != 0)
331341
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);

lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,8 @@ CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
10911091
return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
10921092
case CallingConv::ARM_APCS:
10931093
return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
1094+
case CallingConv::GHC:
1095+
return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
10941096
}
10951097
}
10961098

0 commit comments

Comments
 (0)