diff options
| author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2019-11-04 13:26:38 +0100 |
|---|---|---|
| committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2019-11-04 13:45:51 +0100 |
| commit | 22f9429149a8faed1f5770aca89e68409ae2cc4f (patch) | |
| tree | e783a393bedbacfd5217848b30aded8f6ee9e172 /llvm/lib/Target/SystemZ | |
| parent | 499c90afe9099ff700ca8c8f44a2cbf94b1dd627 (diff) | |
| download | bcm5719-llvm-22f9429149a8faed1f5770aca89e68409ae2cc4f.tar.gz bcm5719-llvm-22f9429149a8faed1f5770aca89e68409ae2cc4f.zip | |
[SystemZ] Add GHC calling convention
This is a special calling convention to be used by the GHC compiler.
Author: Stefan Schulze Frielinghaus
Differential Revision: https://reviews.llvm.org/D69024
Diffstat (limited to 'llvm/lib/Target/SystemZ')
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZCallingConv.h | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZCallingConv.td | 27 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp | 21 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp | 4 |
5 files changed, 77 insertions, 0 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZCallingConv.h b/llvm/lib/Target/SystemZ/SystemZCallingConv.h index 82f29b6361f..4432adc6a26 100644 --- a/llvm/lib/Target/SystemZ/SystemZCallingConv.h +++ b/llvm/lib/Target/SystemZ/SystemZCallingConv.h @@ -124,6 +124,13 @@ inline bool CC_SystemZ_I128Indirect(unsigned &ValNo, MVT &ValVT, return true; } +inline bool CC_SystemZ_GHC_Error(unsigned &, MVT &, MVT &, + CCValAssign::LocInfo &, ISD::ArgFlagsTy &, + CCState &) { + report_fatal_error("No registers left in GHC calling convention"); + return false; +} + } // end namespace llvm #endif diff --git a/llvm/lib/Target/SystemZ/SystemZCallingConv.td b/llvm/lib/Target/SystemZ/SystemZCallingConv.td index bbd51546ac9..b1b7ad47671 100644 --- a/llvm/lib/Target/SystemZ/SystemZCallingConv.td +++ b/llvm/lib/Target/SystemZ/SystemZCallingConv.td @@ -58,9 +58,34 @@ def RetCC_SystemZ : CallingConv<[ ]>; //===----------------------------------------------------------------------===// +// z/Linux argument calling conventions for GHC +//===----------------------------------------------------------------------===// +def CC_SystemZ_GHC : CallingConv<[ + // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, R6, R7, R8, SpLim + CCIfType<[i64], CCAssignToReg<[R7D, R8D, R10D, R11D, R12D, R13D, + R6D, R2D, R3D, R4D, R5D, R9D]>>, + + // Pass in STG registers: F1, ..., F6 + CCIfType<[f32], CCAssignToReg<[F8S, F9S, F10S, F11S, F0S, F1S]>>, + + // Pass in STG registers: D1, ..., D6 + CCIfType<[f64], CCAssignToReg<[F12D, F13D, F14D, F15D, F2D, F3D]>>, + + // Pass in STG registers: XMM1, ..., XMM6 + CCIfSubtarget<"hasVector()", + CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], + CCIfFixed<CCAssignToReg<[V16, V17, V18, V19, V20, V21]>>>>, + + // Fail otherwise + CCCustom<"CC_SystemZ_GHC_Error"> +]>; + +//===----------------------------------------------------------------------===// // z/Linux argument calling conventions //===----------------------------------------------------------------------===// def CC_SystemZ : CallingConv<[ + CCIfCC<"CallingConv::GHC", CCDelegateTo<CC_SystemZ_GHC>>, + // Promote i32 to i64 if it has an explicit extension type. // The convention is that true integer arguments that are smaller // than 64 bits should be marked as extended, but structures that @@ -128,3 +153,5 @@ def CSR_SystemZ_AllRegs : CalleeSavedRegs<(add (sequence "R%dD", 2, 15), def CSR_SystemZ_AllRegs_Vector : CalleeSavedRegs<(add (sequence "R%dD", 2, 15), (sequence "V%d", 0, 31))>; +def CSR_SystemZ_NoRegs : CalleeSavedRegs<(add)>; + diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp index 0b8b6880acc..d183eb5b3eb 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -351,6 +351,23 @@ void SystemZFrameLowering::emitPrologue(MachineFunction &MF, const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo(); bool HasFP = hasFP(MF); + // In GHC calling convention C stack space, including the ABI-defined + // 160-byte base area, is (de)allocated by GHC itself. This stack space may + // be used by LLVM as spill slots for the tail recursive GHC functions. Thus + // do not allocate stack space here, too. + if (MF.getFunction().getCallingConv() == CallingConv::GHC) { + if (MFFrame.getStackSize() > 2048 * sizeof(long)) { + report_fatal_error( + "Pre allocated stack space for GHC function is too small"); + } + if (HasFP) { + report_fatal_error( + "In GHC calling convention a frame pointer is not supported"); + } + MFFrame.setStackSize(MFFrame.getStackSize() + SystemZMC::CallFrameSize); + return; + } + // Debug location must be unknown since the first debug location is used // to determine the end of the prologue. DebugLoc DL; @@ -478,6 +495,10 @@ void SystemZFrameLowering::emitEpilogue(MachineFunction &MF, SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); MachineFrameInfo &MFFrame = MF.getFrameInfo(); + // See SystemZFrameLowering::emitPrologue + if (MF.getFunction().getCallingConv() == CallingConv::GHC) + return; + // Skip the return instruction. assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks"); diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 8e71d834256..daef108b6f0 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1675,6 +1675,9 @@ SystemZTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, if (RetLocs.empty()) return DAG.getNode(SystemZISD::RET_FLAG, DL, MVT::Other, Chain); + if (CallConv == CallingConv::GHC) + report_fatal_error("GHC functions return void only"); + // Copy the result values into the output registers. SDValue Glue; SmallVector<SDValue, 4> RetOps; @@ -2874,6 +2877,10 @@ SDValue SystemZTargetLowering::lowerTLSGetOffset(GlobalAddressSDNode *Node, SDValue Chain = DAG.getEntryNode(); SDValue Glue; + if (DAG.getMachineFunction().getFunction().getCallingConv() == + CallingConv::GHC) + report_fatal_error("In GHC calling convention TLS is not supported"); + // __tls_get_offset takes the GOT offset in %r2 and the GOT in %r12. SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT); Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R12D, GOT, Glue); @@ -2940,6 +2947,10 @@ SDValue SystemZTargetLowering::lowerGlobalTLSAddress(GlobalAddressSDNode *Node, EVT PtrVT = getPointerTy(DAG.getDataLayout()); TLSModel::Model model = DAG.getTarget().getTLSModel(GV); + if (DAG.getMachineFunction().getFunction().getCallingConv() == + CallingConv::GHC) + report_fatal_error("In GHC calling convention TLS is not supported"); + SDValue TP = lowerThreadPointer(DL, DAG); // Get the offset of GA from the thread pointer, based on the TLS model. @@ -3870,6 +3881,9 @@ SDValue SystemZTargetLowering::lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const { MachineFunction &MF = DAG.getMachineFunction(); MF.getInfo<SystemZMachineFunctionInfo>()->setManipulatesSP(true); + if (MF.getFunction().getCallingConv() == CallingConv::GHC) + report_fatal_error("Variable-sized stack allocations are not supported " + "in GHC calling convention"); return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), SystemZ::R15D, Op.getValueType()); } @@ -3880,6 +3894,10 @@ SDValue SystemZTargetLowering::lowerSTACKRESTORE(SDValue Op, MF.getInfo<SystemZMachineFunctionInfo>()->setManipulatesSP(true); bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain"); + if (MF.getFunction().getCallingConv() == CallingConv::GHC) + report_fatal_error("Variable-sized stack allocations are not supported " + "in GHC calling convention"); + SDValue Chain = Op.getOperand(0); SDValue NewSP = Op.getOperand(1); SDValue Backchain; diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp index 39ace5594b7..cbcfc07f2b1 100644 --- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -195,6 +195,8 @@ SystemZRegisterInfo::getRegAllocationHints(unsigned VirtReg, const MCPhysReg * SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>(); + if (MF->getFunction().getCallingConv() == CallingConv::GHC) + return CSR_SystemZ_NoRegs_SaveList; if (MF->getFunction().getCallingConv() == CallingConv::AnyReg) return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_SaveList : CSR_SystemZ_AllRegs_SaveList; @@ -209,6 +211,8 @@ const uint32_t * SystemZRegisterInfo::getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const { const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>(); + if (CC == CallingConv::GHC) + return CSR_SystemZ_NoRegs_RegMask; if (CC == CallingConv::AnyReg) return Subtarget.hasVector()? CSR_SystemZ_AllRegs_Vector_RegMask : CSR_SystemZ_AllRegs_RegMask; |

