diff --git a/llvm/docs/WritingAnLLVMBackend.rst b/llvm/docs/WritingAnLLVMBackend.rst --- a/llvm/docs/WritingAnLLVMBackend.rst +++ b/llvm/docs/WritingAnLLVMBackend.rst @@ -1562,6 +1562,18 @@ CCDelegateTo ]>; +``CCAssignToRegAndStack`` is the same as ``CCAssignToReg``, but also allocates +a stack slot, when some register is used. Basically, it works like: +``CCIf, CCAssignToStack>``. + +.. code-block:: text + + class CCAssignToRegAndStack regList, int size, int align> + : CCAssignToReg { + int Size = size; + int Align = align; + } + Other calling convention interfaces include: * ``CCIf `` --- If the predicate matches, apply the action. diff --git a/llvm/include/llvm/Target/TargetCallingConv.td b/llvm/include/llvm/Target/TargetCallingConv.td --- a/llvm/include/llvm/Target/TargetCallingConv.td +++ b/llvm/include/llvm/Target/TargetCallingConv.td @@ -141,6 +141,15 @@ list ShadowRegList = shadowList; } +/// CCAssignToRegAndStack - Same as CCAssignToReg, but also allocates a stack +/// slot, when some register is used. Basically, it works like: +/// CCIf, CCAssignToStack>. +class CCAssignToRegAndStack regList, int size, int align> + : CCAssignToReg { + int Size = size; + int Align = align; +} + /// CCPassByVal - This action always matches: it assigns the value to a stack /// slot to implement ByVal aggregate parameter passing. Size and alignment /// specify the minimum size and alignment for the stack slot. diff --git a/llvm/lib/Target/SystemZ/SystemZCallingConv.h b/llvm/lib/Target/SystemZ/SystemZCallingConv.h --- a/llvm/lib/Target/SystemZ/SystemZCallingConv.h +++ b/llvm/lib/Target/SystemZ/SystemZCallingConv.h @@ -27,9 +27,6 @@ const unsigned XPLINK64NumArgFPRs = 4; extern const MCPhysReg XPLINK64ArgFPRs[XPLINK64NumArgFPRs]; - - const unsigned XPLINK64NumArgVRs = 8; - extern const MCPhysReg XPLINK64ArgVRs[XPLINK64NumArgVRs]; } // end namespace SystemZ class SystemZCCState : public CCState { @@ -205,41 +202,6 @@ return false; } -inline bool CC_XPLINK64_Shadow_Stack(unsigned &ValNo, MVT &ValVT, MVT &LocVT, - CCValAssign::LocInfo &LocInfo, - ISD::ArgFlagsTy &ArgFlags, - CCState &State) { - ArrayRef RegList; - - switch (LocVT.SimpleTy) { - case MVT::i64: - RegList = SystemZ::XPLINK64ArgGPRs; - break; - case MVT::v16i8: - case MVT::v8i16: - case MVT::v4i32: - case MVT::v2i64: - case MVT::v4f32: - case MVT::v2f64: - RegList = SystemZ::XPLINK64ArgVRs; - break; - case MVT::f32: - case MVT::f64: - case MVT::f128: - RegList = SystemZ::XPLINK64ArgFPRs; - break; - default: - return false; - } - - unsigned UnallocatedRegisterIndex = State.getFirstUnallocated(RegList); - // Every time we can allocate a register, allocate on the stack. - if (UnallocatedRegisterIndex < RegList.size()) - State.AllocateStack(LocVT.getSizeInBits() / 8, Align(8)); - - return false; -} - inline bool RetCC_SystemZ_Error(unsigned &, MVT &, MVT &, CCValAssign::LocInfo &, ISD::ArgFlagsTy &, CCState &) { diff --git a/llvm/lib/Target/SystemZ/SystemZCallingConv.cpp b/llvm/lib/Target/SystemZ/SystemZCallingConv.cpp --- a/llvm/lib/Target/SystemZ/SystemZCallingConv.cpp +++ b/llvm/lib/Target/SystemZ/SystemZCallingConv.cpp @@ -28,7 +28,3 @@ const MCPhysReg SystemZ::XPLINK64ArgFPRs[SystemZ::XPLINK64NumArgFPRs] = { SystemZ::F0D, SystemZ::F2D, SystemZ::F4D, SystemZ::F6D }; - -const MCPhysReg SystemZ::XPLINK64ArgVRs[SystemZ::XPLINK64NumArgVRs] = { - SystemZ::V24, SystemZ::V25, SystemZ::V26, SystemZ::V27, - SystemZ::V28, SystemZ::V29, SystemZ::V30, SystemZ::V31}; diff --git a/llvm/lib/Target/SystemZ/SystemZCallingConv.td b/llvm/lib/Target/SystemZ/SystemZCallingConv.td --- a/llvm/lib/Target/SystemZ/SystemZCallingConv.td +++ b/llvm/lib/Target/SystemZ/SystemZCallingConv.td @@ -247,34 +247,29 @@ // The first 3 integer arguments are passed in registers R1D-R3D. // The rest will be passed in the user area. The address offset of the user // area can be found in register R4D. - CCIfType<[i64], CCCustom<"CC_XPLINK64_Shadow_Stack">>, - CCIfType<[i64], CCAssignToReg<[R1D, R2D, R3D]>>, + CCIfType<[i64], CCAssignToRegAndStack<[R1D, R2D, R3D], 8, 8>>, - // The first 8 named vector arguments are passed in V24-V31. Sub-128 vectors + // The first 8 named vector arguments are passed in V24-V31. Sub-128 vectors // are passed in the same way, but they're widened to one of these types // during type legalization. CCIfSubtarget<"hasVector()", CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - CCIfFixed>>>, - CCIfSubtarget<"hasVector()", - CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - CCIfFixed>>>, + CCIfFixed>>>, CCIfSubtarget<"hasVector()", CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - CCIfFixed>>>, + CCIfFixed>>>, - // The first 4 named float and double arguments are passed in registers FPR0-FPR6. - // The rest will be passed in the user area. + // The first 4 named float and double arguments are passed in registers + // FPR0-FPR6. The rest will be passed in the user area. CCIfType<[f32, f64], CCIfFixed>>, - CCIfType<[f32, f64], CCIfFixed>>, - CCIfType<[f32], CCIfFixed>>, - CCIfType<[f64], CCIfFixed>>, + CCIfType<[f32], CCIfFixed>>, + CCIfType<[f64], CCIfFixed>>, + // The first 2 long double arguments are passed in register FPR0/FPR2 // and FPR4/FPR6. The rest will be passed in the user area. CCIfType<[f128], CCIfFixed>>, - CCIfType<[f128], CCIfFixed>>, - CCIfType<[f128], CCIfFixed>>, + CCIfType<[f128], CCIfFixed>>, // Other arguments are passed in 8-byte-aligned 8-byte stack slots. CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>, diff --git a/llvm/utils/TableGen/CallingConvEmitter.cpp b/llvm/utils/TableGen/CallingConvEmitter.cpp --- a/llvm/utils/TableGen/CallingConvEmitter.cpp +++ b/llvm/utils/TableGen/CallingConvEmitter.cpp @@ -149,7 +149,8 @@ << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n" << IndentStr << " return false;\n"; DelegateToMap[CurrentAction].insert(CC->getName().str()); - } else if (Action->isSubClassOf("CCAssignToReg")) { + } else if (Action->isSubClassOf("CCAssignToReg") || + Action->isSubClassOf("CCAssignToRegAndStack")) { ListInit *RegList = Action->getValueAsListInit("RegList"); if (RegList->size() == 1) { std::string Name = getQualifiedName(RegList->getElementAsRecord(0)); @@ -178,6 +179,28 @@ } O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, " << "Reg, LocVT, LocInfo));\n"; + if (Action->isSubClassOf("CCAssignToRegAndStack")) { + int Size = Action->getValueAsInt("Size"); + int Align = Action->getValueAsInt("Align"); + O << IndentStr << " (void)State.AllocateStack("; + if (Size) + O << Size << ", "; + else + O << "\n" + << IndentStr + << " State.getMachineFunction().getDataLayout()." + "getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext()))," + " "; + if (Align) + O << "Align(" << Align << ")"; + else + O << "\n" + << IndentStr + << " State.getMachineFunction().getDataLayout()." + "getABITypeAlign(EVT(LocVT).getTypeForEVT(State.getContext()" + "))"; + O << ");\n"; + } O << IndentStr << " return false;\n"; O << IndentStr << "}\n"; } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) {