1 //===-- PPCCallingConv.cpp - ------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "PPCRegisterInfo.h" 10 #include "PPCCallingConv.h" 11 #include "PPCSubtarget.h" 12 #include "PPCCCState.h" 13 using namespace llvm; 14 15 inline bool CC_PPC_AnyReg_Error(unsigned &, MVT &, MVT &, 16 CCValAssign::LocInfo &, ISD::ArgFlagsTy &, 17 CCState &) { 18 llvm_unreachable("The AnyReg calling convention is only supported by the " \ 19 "stackmap and patchpoint intrinsics."); 20 // gracefully fallback to PPC C calling convention on Release builds. 21 return false; 22 } 23 24 // This function handles the shadowing of GPRs for fp and vector types, 25 // and is a depiction of the algorithm described in the ELFv2 ABI, 26 // Section 2.2.4.1: Parameter Passing Register Selection Algorithm. 27 inline bool CC_PPC64_ELF_Shadow_GPR_Regs(unsigned &ValNo, MVT &ValVT, 28 MVT &LocVT, 29 CCValAssign::LocInfo &LocInfo, 30 ISD::ArgFlagsTy &ArgFlags, 31 CCState &State) { 32 33 // The 64-bit ELFv2 ABI-defined parameter passing general purpose registers. 34 static const MCPhysReg ELF64ArgGPRs[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6, 35 PPC::X7, PPC::X8, PPC::X9, PPC::X10}; 36 const unsigned ELF64NumArgGPRs = std::size(ELF64ArgGPRs); 37 38 unsigned FirstUnallocGPR = State.getFirstUnallocated(ELF64ArgGPRs); 39 if (FirstUnallocGPR == ELF64NumArgGPRs) 40 return false; 41 42 // As described in 2.2.4.1 under the "float" section, shadow a single GPR 43 // for single/double precision. ppcf128 gets broken up into two doubles 44 // and will also shadow GPRs within this section. 45 if (LocVT == MVT::f32 || LocVT == MVT::f64) 46 State.AllocateReg(ELF64ArgGPRs); 47 else if (LocVT.is128BitVector() || (LocVT == MVT::f128)) { 48 // For vector and __float128 (which is represents the "vector" section 49 // in 2.2.4.1), shadow two even GPRs (skipping the odd one if it is next 50 // in the allocation order). To check if the GPR is even, the specific 51 // condition checks if the register allocated is odd, because the even 52 // physical registers are odd values. 53 if ((State.AllocateReg(ELF64ArgGPRs) - PPC::X3) % 2 == 1) 54 State.AllocateReg(ELF64ArgGPRs); 55 State.AllocateReg(ELF64ArgGPRs); 56 } 57 return false; 58 } 59 60 static bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 61 CCValAssign::LocInfo &LocInfo, 62 ISD::ArgFlagsTy &ArgFlags, 63 CCState &State) { 64 return true; 65 } 66 67 static bool CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT, 68 MVT &LocVT, 69 CCValAssign::LocInfo &LocInfo, 70 ISD::ArgFlagsTy &ArgFlags, 71 CCState &State) { 72 static const MCPhysReg ArgRegs[] = { 73 PPC::R3, PPC::R4, PPC::R5, PPC::R6, 74 PPC::R7, PPC::R8, PPC::R9, PPC::R10, 75 }; 76 const unsigned NumArgRegs = std::size(ArgRegs); 77 78 unsigned RegNum = State.getFirstUnallocated(ArgRegs); 79 80 // Skip one register if the first unallocated register has an even register 81 // number and there are still argument registers available which have not been 82 // allocated yet. RegNum is actually an index into ArgRegs, which means we 83 // need to skip a register if RegNum is odd. 84 if (RegNum != NumArgRegs && RegNum % 2 == 1) { 85 State.AllocateReg(ArgRegs[RegNum]); 86 } 87 88 // Always return false here, as this function only makes sure that the first 89 // unallocated register has an odd register number and does not actually 90 // allocate a register for the current argument. 91 return false; 92 } 93 94 static bool CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128( 95 unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, 96 ISD::ArgFlagsTy &ArgFlags, CCState &State) { 97 static const MCPhysReg ArgRegs[] = { 98 PPC::R3, PPC::R4, PPC::R5, PPC::R6, 99 PPC::R7, PPC::R8, PPC::R9, PPC::R10, 100 }; 101 const unsigned NumArgRegs = std::size(ArgRegs); 102 103 unsigned RegNum = State.getFirstUnallocated(ArgRegs); 104 int RegsLeft = NumArgRegs - RegNum; 105 106 // Skip if there is not enough registers left for long double type (4 gpr regs 107 // in soft float mode) and put long double argument on the stack. 108 if (RegNum != NumArgRegs && RegsLeft < 4) { 109 for (int i = 0; i < RegsLeft; i++) { 110 State.AllocateReg(ArgRegs[RegNum + i]); 111 } 112 } 113 114 return false; 115 } 116 117 static bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT, 118 MVT &LocVT, 119 CCValAssign::LocInfo &LocInfo, 120 ISD::ArgFlagsTy &ArgFlags, 121 CCState &State) { 122 static const MCPhysReg ArgRegs[] = { 123 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, 124 PPC::F8 125 }; 126 127 const unsigned NumArgRegs = std::size(ArgRegs); 128 129 unsigned RegNum = State.getFirstUnallocated(ArgRegs); 130 131 // If there is only one Floating-point register left we need to put both f64 132 // values of a split ppc_fp128 value on the stack. 133 if (RegNum != NumArgRegs && ArgRegs[RegNum] == PPC::F8) { 134 State.AllocateReg(ArgRegs[RegNum]); 135 } 136 137 // Always return false here, as this function only makes sure that the two f64 138 // values a ppc_fp128 value is split into are both passed in registers or both 139 // passed on the stack and does not actually allocate a register for the 140 // current argument. 141 return false; 142 } 143 144 // Split F64 arguments into two 32-bit consecutive registers. 145 static bool CC_PPC32_SPE_CustomSplitFP64(unsigned &ValNo, MVT &ValVT, 146 MVT &LocVT, 147 CCValAssign::LocInfo &LocInfo, 148 ISD::ArgFlagsTy &ArgFlags, 149 CCState &State) { 150 static const MCPhysReg HiRegList[] = { PPC::R3, PPC::R5, PPC::R7, PPC::R9 }; 151 static const MCPhysReg LoRegList[] = { PPC::R4, PPC::R6, PPC::R8, PPC::R10 }; 152 153 // Try to get the first register. 154 unsigned Reg = State.AllocateReg(HiRegList); 155 if (!Reg) 156 return false; 157 158 unsigned i; 159 for (i = 0; i < std::size(HiRegList); ++i) 160 if (HiRegList[i] == Reg) 161 break; 162 163 unsigned T = State.AllocateReg(LoRegList[i]); 164 (void)T; 165 assert(T == LoRegList[i] && "Could not allocate register"); 166 167 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 168 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i], 169 LocVT, LocInfo)); 170 return true; 171 } 172 173 // Same as above, but for return values, so only allocate for R3 and R4 174 static bool CC_PPC32_SPE_RetF64(unsigned &ValNo, MVT &ValVT, 175 MVT &LocVT, 176 CCValAssign::LocInfo &LocInfo, 177 ISD::ArgFlagsTy &ArgFlags, 178 CCState &State) { 179 static const MCPhysReg HiRegList[] = { PPC::R3 }; 180 static const MCPhysReg LoRegList[] = { PPC::R4 }; 181 182 // Try to get the first register. 183 unsigned Reg = State.AllocateReg(HiRegList, LoRegList); 184 if (!Reg) 185 return false; 186 187 unsigned i; 188 for (i = 0; i < std::size(HiRegList); ++i) 189 if (HiRegList[i] == Reg) 190 break; 191 192 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 193 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i], 194 LocVT, LocInfo)); 195 return true; 196 } 197 198 #include "PPCGenCallingConv.inc" 199