1 //===-- RISCVCallingConv.cpp - RISC-V Custom CC Routines ------------------===// 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 // This file contains the custom routines for the RISC-V Calling Convention. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "RISCVCallingConv.h" 14 #include "RISCVSubtarget.h" 15 #include "llvm/IR/DataLayout.h" 16 #include "llvm/IR/Module.h" 17 #include "llvm/MC/MCRegister.h" 18 19 using namespace llvm; 20 21 // Calling Convention Implementation. 22 // The expectations for frontend ABI lowering vary from target to target. 23 // Ideally, an LLVM frontend would be able to avoid worrying about many ABI 24 // details, but this is a longer term goal. For now, we simply try to keep the 25 // role of the frontend as simple and well-defined as possible. The rules can 26 // be summarised as: 27 // * Never split up large scalar arguments. We handle them here. 28 // * If a hardfloat calling convention is being used, and the struct may be 29 // passed in a pair of registers (fp+fp, int+fp), and both registers are 30 // available, then pass as two separate arguments. If either the GPRs or FPRs 31 // are exhausted, then pass according to the rule below. 32 // * If a struct could never be passed in registers or directly in a stack 33 // slot (as it is larger than 2*XLEN and the floating point rules don't 34 // apply), then pass it using a pointer with the byval attribute. 35 // * If a struct is less than 2*XLEN, then coerce to either a two-element 36 // word-sized array or a 2*XLEN scalar (depending on alignment). 37 // * The frontend can determine whether a struct is returned by reference or 38 // not based on its size and fields. If it will be returned by reference, the 39 // frontend must modify the prototype so a pointer with the sret annotation is 40 // passed as the first argument. This is not necessary for large scalar 41 // returns. 42 // * Struct return values and varargs should be coerced to structs containing 43 // register-size fields in the same situations they would be for fixed 44 // arguments. 45 46 static const MCPhysReg ArgFPR16s[] = {RISCV::F10_H, RISCV::F11_H, RISCV::F12_H, 47 RISCV::F13_H, RISCV::F14_H, RISCV::F15_H, 48 RISCV::F16_H, RISCV::F17_H}; 49 static const MCPhysReg ArgFPR32s[] = {RISCV::F10_F, RISCV::F11_F, RISCV::F12_F, 50 RISCV::F13_F, RISCV::F14_F, RISCV::F15_F, 51 RISCV::F16_F, RISCV::F17_F}; 52 static const MCPhysReg ArgFPR64s[] = {RISCV::F10_D, RISCV::F11_D, RISCV::F12_D, 53 RISCV::F13_D, RISCV::F14_D, RISCV::F15_D, 54 RISCV::F16_D, RISCV::F17_D}; 55 // This is an interim calling convention and it may be changed in the future. 56 static const MCPhysReg ArgVRs[] = { 57 RISCV::V8, RISCV::V9, RISCV::V10, RISCV::V11, RISCV::V12, RISCV::V13, 58 RISCV::V14, RISCV::V15, RISCV::V16, RISCV::V17, RISCV::V18, RISCV::V19, 59 RISCV::V20, RISCV::V21, RISCV::V22, RISCV::V23}; 60 static const MCPhysReg ArgVRM2s[] = {RISCV::V8M2, RISCV::V10M2, RISCV::V12M2, 61 RISCV::V14M2, RISCV::V16M2, RISCV::V18M2, 62 RISCV::V20M2, RISCV::V22M2}; 63 static const MCPhysReg ArgVRM4s[] = {RISCV::V8M4, RISCV::V12M4, RISCV::V16M4, 64 RISCV::V20M4}; 65 static const MCPhysReg ArgVRM8s[] = {RISCV::V8M8, RISCV::V16M8}; 66 static const MCPhysReg ArgVRN2M1s[] = { 67 RISCV::V8_V9, RISCV::V9_V10, RISCV::V10_V11, RISCV::V11_V12, 68 RISCV::V12_V13, RISCV::V13_V14, RISCV::V14_V15, RISCV::V15_V16, 69 RISCV::V16_V17, RISCV::V17_V18, RISCV::V18_V19, RISCV::V19_V20, 70 RISCV::V20_V21, RISCV::V21_V22, RISCV::V22_V23}; 71 static const MCPhysReg ArgVRN3M1s[] = { 72 RISCV::V8_V9_V10, RISCV::V9_V10_V11, RISCV::V10_V11_V12, 73 RISCV::V11_V12_V13, RISCV::V12_V13_V14, RISCV::V13_V14_V15, 74 RISCV::V14_V15_V16, RISCV::V15_V16_V17, RISCV::V16_V17_V18, 75 RISCV::V17_V18_V19, RISCV::V18_V19_V20, RISCV::V19_V20_V21, 76 RISCV::V20_V21_V22, RISCV::V21_V22_V23}; 77 static const MCPhysReg ArgVRN4M1s[] = { 78 RISCV::V8_V9_V10_V11, RISCV::V9_V10_V11_V12, RISCV::V10_V11_V12_V13, 79 RISCV::V11_V12_V13_V14, RISCV::V12_V13_V14_V15, RISCV::V13_V14_V15_V16, 80 RISCV::V14_V15_V16_V17, RISCV::V15_V16_V17_V18, RISCV::V16_V17_V18_V19, 81 RISCV::V17_V18_V19_V20, RISCV::V18_V19_V20_V21, RISCV::V19_V20_V21_V22, 82 RISCV::V20_V21_V22_V23}; 83 static const MCPhysReg ArgVRN5M1s[] = { 84 RISCV::V8_V9_V10_V11_V12, RISCV::V9_V10_V11_V12_V13, 85 RISCV::V10_V11_V12_V13_V14, RISCV::V11_V12_V13_V14_V15, 86 RISCV::V12_V13_V14_V15_V16, RISCV::V13_V14_V15_V16_V17, 87 RISCV::V14_V15_V16_V17_V18, RISCV::V15_V16_V17_V18_V19, 88 RISCV::V16_V17_V18_V19_V20, RISCV::V17_V18_V19_V20_V21, 89 RISCV::V18_V19_V20_V21_V22, RISCV::V19_V20_V21_V22_V23}; 90 static const MCPhysReg ArgVRN6M1s[] = { 91 RISCV::V8_V9_V10_V11_V12_V13, RISCV::V9_V10_V11_V12_V13_V14, 92 RISCV::V10_V11_V12_V13_V14_V15, RISCV::V11_V12_V13_V14_V15_V16, 93 RISCV::V12_V13_V14_V15_V16_V17, RISCV::V13_V14_V15_V16_V17_V18, 94 RISCV::V14_V15_V16_V17_V18_V19, RISCV::V15_V16_V17_V18_V19_V20, 95 RISCV::V16_V17_V18_V19_V20_V21, RISCV::V17_V18_V19_V20_V21_V22, 96 RISCV::V18_V19_V20_V21_V22_V23}; 97 static const MCPhysReg ArgVRN7M1s[] = { 98 RISCV::V8_V9_V10_V11_V12_V13_V14, RISCV::V9_V10_V11_V12_V13_V14_V15, 99 RISCV::V10_V11_V12_V13_V14_V15_V16, RISCV::V11_V12_V13_V14_V15_V16_V17, 100 RISCV::V12_V13_V14_V15_V16_V17_V18, RISCV::V13_V14_V15_V16_V17_V18_V19, 101 RISCV::V14_V15_V16_V17_V18_V19_V20, RISCV::V15_V16_V17_V18_V19_V20_V21, 102 RISCV::V16_V17_V18_V19_V20_V21_V22, RISCV::V17_V18_V19_V20_V21_V22_V23}; 103 static const MCPhysReg ArgVRN8M1s[] = {RISCV::V8_V9_V10_V11_V12_V13_V14_V15, 104 RISCV::V9_V10_V11_V12_V13_V14_V15_V16, 105 RISCV::V10_V11_V12_V13_V14_V15_V16_V17, 106 RISCV::V11_V12_V13_V14_V15_V16_V17_V18, 107 RISCV::V12_V13_V14_V15_V16_V17_V18_V19, 108 RISCV::V13_V14_V15_V16_V17_V18_V19_V20, 109 RISCV::V14_V15_V16_V17_V18_V19_V20_V21, 110 RISCV::V15_V16_V17_V18_V19_V20_V21_V22, 111 RISCV::V16_V17_V18_V19_V20_V21_V22_V23}; 112 static const MCPhysReg ArgVRN2M2s[] = {RISCV::V8M2_V10M2, RISCV::V10M2_V12M2, 113 RISCV::V12M2_V14M2, RISCV::V14M2_V16M2, 114 RISCV::V16M2_V18M2, RISCV::V18M2_V20M2, 115 RISCV::V20M2_V22M2}; 116 static const MCPhysReg ArgVRN3M2s[] = { 117 RISCV::V8M2_V10M2_V12M2, RISCV::V10M2_V12M2_V14M2, 118 RISCV::V12M2_V14M2_V16M2, RISCV::V14M2_V16M2_V18M2, 119 RISCV::V16M2_V18M2_V20M2, RISCV::V18M2_V20M2_V22M2}; 120 static const MCPhysReg ArgVRN4M2s[] = { 121 RISCV::V8M2_V10M2_V12M2_V14M2, RISCV::V10M2_V12M2_V14M2_V16M2, 122 RISCV::V12M2_V14M2_V16M2_V18M2, RISCV::V14M2_V16M2_V18M2_V20M2, 123 RISCV::V16M2_V18M2_V20M2_V22M2}; 124 static const MCPhysReg ArgVRN2M4s[] = {RISCV::V8M4_V12M4, RISCV::V12M4_V16M4, 125 RISCV::V16M4_V20M4}; 126 127 ArrayRef<MCPhysReg> RISCV::getArgGPRs(const RISCVABI::ABI ABI) { 128 // The GPRs used for passing arguments in the ILP32* and LP64* ABIs, except 129 // the ILP32E ABI. 130 static const MCPhysReg ArgIGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12, 131 RISCV::X13, RISCV::X14, RISCV::X15, 132 RISCV::X16, RISCV::X17}; 133 // The GPRs used for passing arguments in the ILP32E/LP64E ABI. 134 static const MCPhysReg ArgEGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12, 135 RISCV::X13, RISCV::X14, RISCV::X15}; 136 137 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E) 138 return ArrayRef(ArgEGPRs); 139 140 return ArrayRef(ArgIGPRs); 141 } 142 143 static ArrayRef<MCPhysReg> getArgGPR16s(const RISCVABI::ABI ABI) { 144 // The GPRs used for passing arguments in the ILP32* and LP64* ABIs, except 145 // the ILP32E ABI. 146 static const MCPhysReg ArgIGPRs[] = {RISCV::X10_H, RISCV::X11_H, RISCV::X12_H, 147 RISCV::X13_H, RISCV::X14_H, RISCV::X15_H, 148 RISCV::X16_H, RISCV::X17_H}; 149 // The GPRs used for passing arguments in the ILP32E/LP64E ABI. 150 static const MCPhysReg ArgEGPRs[] = {RISCV::X10_H, RISCV::X11_H, 151 RISCV::X12_H, RISCV::X13_H, 152 RISCV::X14_H, RISCV::X15_H}; 153 154 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E) 155 return ArrayRef(ArgEGPRs); 156 157 return ArrayRef(ArgIGPRs); 158 } 159 160 static ArrayRef<MCPhysReg> getArgGPR32s(const RISCVABI::ABI ABI) { 161 // The GPRs used for passing arguments in the ILP32* and LP64* ABIs, except 162 // the ILP32E ABI. 163 static const MCPhysReg ArgIGPRs[] = {RISCV::X10_W, RISCV::X11_W, RISCV::X12_W, 164 RISCV::X13_W, RISCV::X14_W, RISCV::X15_W, 165 RISCV::X16_W, RISCV::X17_W}; 166 // The GPRs used for passing arguments in the ILP32E/LP64E ABI. 167 static const MCPhysReg ArgEGPRs[] = {RISCV::X10_W, RISCV::X11_W, 168 RISCV::X12_W, RISCV::X13_W, 169 RISCV::X14_W, RISCV::X15_W}; 170 171 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E) 172 return ArrayRef(ArgEGPRs); 173 174 return ArrayRef(ArgIGPRs); 175 } 176 177 static ArrayRef<MCPhysReg> getFastCCArgGPRs(const RISCVABI::ABI ABI) { 178 // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used 179 // for save-restore libcall, so we don't use them. 180 // Don't use X7 for fastcc, since Zicfilp uses X7 as the label register. 181 static const MCPhysReg FastCCIGPRs[] = { 182 RISCV::X10, RISCV::X11, RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, 183 RISCV::X16, RISCV::X17, RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31}; 184 185 // The GPRs used for passing arguments in the FastCC when using ILP32E/LP64E. 186 static const MCPhysReg FastCCEGPRs[] = {RISCV::X10, RISCV::X11, RISCV::X12, 187 RISCV::X13, RISCV::X14, RISCV::X15}; 188 189 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E) 190 return ArrayRef(FastCCEGPRs); 191 192 return ArrayRef(FastCCIGPRs); 193 } 194 195 static ArrayRef<MCPhysReg> getFastCCArgGPRF16s(const RISCVABI::ABI ABI) { 196 // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used 197 // for save-restore libcall, so we don't use them. 198 // Don't use X7 for fastcc, since Zicfilp uses X7 as the label register. 199 static const MCPhysReg FastCCIGPRs[] = { 200 RISCV::X10_H, RISCV::X11_H, RISCV::X12_H, RISCV::X13_H, 201 RISCV::X14_H, RISCV::X15_H, RISCV::X16_H, RISCV::X17_H, 202 RISCV::X28_H, RISCV::X29_H, RISCV::X30_H, RISCV::X31_H}; 203 204 // The GPRs used for passing arguments in the FastCC when using ILP32E/LP64E. 205 static const MCPhysReg FastCCEGPRs[] = {RISCV::X10_H, RISCV::X11_H, 206 RISCV::X12_H, RISCV::X13_H, 207 RISCV::X14_H, RISCV::X15_H}; 208 209 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E) 210 return ArrayRef(FastCCEGPRs); 211 212 return ArrayRef(FastCCIGPRs); 213 } 214 215 static ArrayRef<MCPhysReg> getFastCCArgGPRF32s(const RISCVABI::ABI ABI) { 216 // The GPRs used for passing arguments in the FastCC, X5 and X6 might be used 217 // for save-restore libcall, so we don't use them. 218 // Don't use X7 for fastcc, since Zicfilp uses X7 as the label register. 219 static const MCPhysReg FastCCIGPRs[] = { 220 RISCV::X10_W, RISCV::X11_W, RISCV::X12_W, RISCV::X13_W, 221 RISCV::X14_W, RISCV::X15_W, RISCV::X16_W, RISCV::X17_W, 222 RISCV::X28_W, RISCV::X29_W, RISCV::X30_W, RISCV::X31_W}; 223 224 // The GPRs used for passing arguments in the FastCC when using ILP32E/LP64E. 225 static const MCPhysReg FastCCEGPRs[] = {RISCV::X10_W, RISCV::X11_W, 226 RISCV::X12_W, RISCV::X13_W, 227 RISCV::X14_W, RISCV::X15_W}; 228 229 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E) 230 return ArrayRef(FastCCEGPRs); 231 232 return ArrayRef(FastCCIGPRs); 233 } 234 235 // Pass a 2*XLEN argument that has been split into two XLEN values through 236 // registers or the stack as necessary. 237 static bool CC_RISCVAssign2XLen(unsigned XLen, CCState &State, CCValAssign VA1, 238 ISD::ArgFlagsTy ArgFlags1, unsigned ValNo2, 239 MVT ValVT2, MVT LocVT2, 240 ISD::ArgFlagsTy ArgFlags2, bool EABI) { 241 unsigned XLenInBytes = XLen / 8; 242 const RISCVSubtarget &STI = 243 State.getMachineFunction().getSubtarget<RISCVSubtarget>(); 244 ArrayRef<MCPhysReg> ArgGPRs = RISCV::getArgGPRs(STI.getTargetABI()); 245 246 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) { 247 // At least one half can be passed via register. 248 State.addLoc(CCValAssign::getReg(VA1.getValNo(), VA1.getValVT(), Reg, 249 VA1.getLocVT(), CCValAssign::Full)); 250 } else { 251 // Both halves must be passed on the stack, with proper alignment. 252 // TODO: To be compatible with GCC's behaviors, we force them to have 4-byte 253 // alignment. This behavior may be changed when RV32E/ILP32E is ratified. 254 Align StackAlign(XLenInBytes); 255 if (!EABI || XLen != 32) 256 StackAlign = std::max(StackAlign, ArgFlags1.getNonZeroOrigAlign()); 257 State.addLoc( 258 CCValAssign::getMem(VA1.getValNo(), VA1.getValVT(), 259 State.AllocateStack(XLenInBytes, StackAlign), 260 VA1.getLocVT(), CCValAssign::Full)); 261 State.addLoc(CCValAssign::getMem( 262 ValNo2, ValVT2, State.AllocateStack(XLenInBytes, Align(XLenInBytes)), 263 LocVT2, CCValAssign::Full)); 264 return false; 265 } 266 267 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) { 268 // The second half can also be passed via register. 269 State.addLoc( 270 CCValAssign::getReg(ValNo2, ValVT2, Reg, LocVT2, CCValAssign::Full)); 271 } else { 272 // The second half is passed via the stack, without additional alignment. 273 State.addLoc(CCValAssign::getMem( 274 ValNo2, ValVT2, State.AllocateStack(XLenInBytes, Align(XLenInBytes)), 275 LocVT2, CCValAssign::Full)); 276 } 277 278 return false; 279 } 280 281 static MCRegister allocateRVVReg(MVT ValVT, unsigned ValNo, CCState &State, 282 const RISCVTargetLowering &TLI) { 283 const TargetRegisterClass *RC = TLI.getRegClassFor(ValVT); 284 if (RC == &RISCV::VRRegClass) { 285 // Assign the first mask argument to V0. 286 // This is an interim calling convention and it may be changed in the 287 // future. 288 if (ValVT.getVectorElementType() == MVT::i1) 289 if (MCRegister Reg = State.AllocateReg(RISCV::V0)) 290 return Reg; 291 return State.AllocateReg(ArgVRs); 292 } 293 if (RC == &RISCV::VRM2RegClass) 294 return State.AllocateReg(ArgVRM2s); 295 if (RC == &RISCV::VRM4RegClass) 296 return State.AllocateReg(ArgVRM4s); 297 if (RC == &RISCV::VRM8RegClass) 298 return State.AllocateReg(ArgVRM8s); 299 if (RC == &RISCV::VRN2M1RegClass) 300 return State.AllocateReg(ArgVRN2M1s); 301 if (RC == &RISCV::VRN3M1RegClass) 302 return State.AllocateReg(ArgVRN3M1s); 303 if (RC == &RISCV::VRN4M1RegClass) 304 return State.AllocateReg(ArgVRN4M1s); 305 if (RC == &RISCV::VRN5M1RegClass) 306 return State.AllocateReg(ArgVRN5M1s); 307 if (RC == &RISCV::VRN6M1RegClass) 308 return State.AllocateReg(ArgVRN6M1s); 309 if (RC == &RISCV::VRN7M1RegClass) 310 return State.AllocateReg(ArgVRN7M1s); 311 if (RC == &RISCV::VRN8M1RegClass) 312 return State.AllocateReg(ArgVRN8M1s); 313 if (RC == &RISCV::VRN2M2RegClass) 314 return State.AllocateReg(ArgVRN2M2s); 315 if (RC == &RISCV::VRN3M2RegClass) 316 return State.AllocateReg(ArgVRN3M2s); 317 if (RC == &RISCV::VRN4M2RegClass) 318 return State.AllocateReg(ArgVRN4M2s); 319 if (RC == &RISCV::VRN2M4RegClass) 320 return State.AllocateReg(ArgVRN2M4s); 321 llvm_unreachable("Unhandled register class for ValueType"); 322 } 323 324 // Implements the RISC-V calling convention. Returns true upon failure. 325 bool llvm::CC_RISCV(unsigned ValNo, MVT ValVT, MVT LocVT, 326 CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, 327 CCState &State, bool IsFixed, bool IsRet, Type *OrigTy) { 328 const MachineFunction &MF = State.getMachineFunction(); 329 const DataLayout &DL = MF.getDataLayout(); 330 const RISCVSubtarget &Subtarget = MF.getSubtarget<RISCVSubtarget>(); 331 const RISCVTargetLowering &TLI = *Subtarget.getTargetLowering(); 332 333 unsigned XLen = Subtarget.getXLen(); 334 MVT XLenVT = Subtarget.getXLenVT(); 335 336 if (ArgFlags.isNest()) { 337 // Static chain parameter must not be passed in normal argument registers, 338 // so we assign t2/t3 for it as done in GCC's 339 // __builtin_call_with_static_chain 340 bool HasCFBranch = 341 Subtarget.hasStdExtZicfilp() && 342 MF.getFunction().getParent()->getModuleFlag("cf-protection-branch"); 343 344 // Normal: t2, Branch control flow protection: t3 345 const auto StaticChainReg = HasCFBranch ? RISCV::X28 : RISCV::X7; 346 347 RISCVABI::ABI ABI = Subtarget.getTargetABI(); 348 if (HasCFBranch && 349 (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)) 350 reportFatalUsageError( 351 "Nested functions with control flow protection are not " 352 "usable with ILP32E or LP64E ABI."); 353 if (MCRegister Reg = State.AllocateReg(StaticChainReg)) { 354 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 355 return false; 356 } 357 } 358 359 // Any return value split in to more than two values can't be returned 360 // directly. Vectors are returned via the available vector registers. 361 if (!LocVT.isVector() && IsRet && ValNo > 1) 362 return true; 363 364 // UseGPRForF16_F32 if targeting one of the soft-float ABIs, if passing a 365 // variadic argument, or if no F16/F32 argument registers are available. 366 bool UseGPRForF16_F32 = true; 367 // UseGPRForF64 if targeting soft-float ABIs or an FLEN=32 ABI, if passing a 368 // variadic argument, or if no F64 argument registers are available. 369 bool UseGPRForF64 = true; 370 371 RISCVABI::ABI ABI = Subtarget.getTargetABI(); 372 switch (ABI) { 373 default: 374 llvm_unreachable("Unexpected ABI"); 375 case RISCVABI::ABI_ILP32: 376 case RISCVABI::ABI_ILP32E: 377 case RISCVABI::ABI_LP64: 378 case RISCVABI::ABI_LP64E: 379 break; 380 case RISCVABI::ABI_ILP32F: 381 case RISCVABI::ABI_LP64F: 382 UseGPRForF16_F32 = !IsFixed; 383 break; 384 case RISCVABI::ABI_ILP32D: 385 case RISCVABI::ABI_LP64D: 386 UseGPRForF16_F32 = !IsFixed; 387 UseGPRForF64 = !IsFixed; 388 break; 389 } 390 391 if ((LocVT == MVT::f16 || LocVT == MVT::bf16) && !UseGPRForF16_F32) { 392 if (MCRegister Reg = State.AllocateReg(ArgFPR16s)) { 393 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 394 return false; 395 } 396 } 397 398 if (LocVT == MVT::f32 && !UseGPRForF16_F32) { 399 if (MCRegister Reg = State.AllocateReg(ArgFPR32s)) { 400 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 401 return false; 402 } 403 } 404 405 if (LocVT == MVT::f64 && !UseGPRForF64) { 406 if (MCRegister Reg = State.AllocateReg(ArgFPR64s)) { 407 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 408 return false; 409 } 410 } 411 412 if ((ValVT == MVT::f16 && Subtarget.hasStdExtZhinxmin())) { 413 if (MCRegister Reg = State.AllocateReg(getArgGPR16s(ABI))) { 414 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 415 return false; 416 } 417 } 418 419 if (ValVT == MVT::f32 && Subtarget.hasStdExtZfinx()) { 420 if (MCRegister Reg = State.AllocateReg(getArgGPR32s(ABI))) { 421 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 422 return false; 423 } 424 } 425 426 ArrayRef<MCPhysReg> ArgGPRs = RISCV::getArgGPRs(ABI); 427 428 // Zdinx use GPR without a bitcast when possible. 429 if (LocVT == MVT::f64 && XLen == 64 && Subtarget.hasStdExtZdinx()) { 430 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) { 431 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 432 return false; 433 } 434 } 435 436 // FP smaller than XLen, uses custom GPR. 437 if (LocVT == MVT::f16 || LocVT == MVT::bf16 || 438 (LocVT == MVT::f32 && XLen == 64)) { 439 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) { 440 LocVT = XLenVT; 441 State.addLoc( 442 CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 443 return false; 444 } 445 } 446 447 // Bitcast FP to GPR if we can use a GPR register. 448 if ((XLen == 32 && LocVT == MVT::f32) || (XLen == 64 && LocVT == MVT::f64)) { 449 if (MCRegister Reg = State.AllocateReg(ArgGPRs)) { 450 LocVT = XLenVT; 451 LocInfo = CCValAssign::BCvt; 452 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 453 return false; 454 } 455 } 456 457 // If this is a variadic argument, the RISC-V calling convention requires 458 // that it is assigned an 'even' or 'aligned' register if it has 8-byte 459 // alignment (RV32) or 16-byte alignment (RV64). An aligned register should 460 // be used regardless of whether the original argument was split during 461 // legalisation or not. The argument will not be passed by registers if the 462 // original type is larger than 2*XLEN, so the register alignment rule does 463 // not apply. 464 // TODO: To be compatible with GCC's behaviors, we don't align registers 465 // currently if we are using ILP32E calling convention. This behavior may be 466 // changed when RV32E/ILP32E is ratified. 467 unsigned TwoXLenInBytes = (2 * XLen) / 8; 468 if (!IsFixed && ArgFlags.getNonZeroOrigAlign() == TwoXLenInBytes && 469 DL.getTypeAllocSize(OrigTy) == TwoXLenInBytes && 470 ABI != RISCVABI::ABI_ILP32E) { 471 unsigned RegIdx = State.getFirstUnallocated(ArgGPRs); 472 // Skip 'odd' register if necessary. 473 if (RegIdx != std::size(ArgGPRs) && RegIdx % 2 == 1) 474 State.AllocateReg(ArgGPRs); 475 } 476 477 SmallVectorImpl<CCValAssign> &PendingLocs = State.getPendingLocs(); 478 SmallVectorImpl<ISD::ArgFlagsTy> &PendingArgFlags = 479 State.getPendingArgFlags(); 480 481 assert(PendingLocs.size() == PendingArgFlags.size() && 482 "PendingLocs and PendingArgFlags out of sync"); 483 484 // Handle passing f64 on RV32D with a soft float ABI or when floating point 485 // registers are exhausted. 486 if (XLen == 32 && LocVT == MVT::f64) { 487 assert(PendingLocs.empty() && "Can't lower f64 if it is split"); 488 // Depending on available argument GPRS, f64 may be passed in a pair of 489 // GPRs, split between a GPR and the stack, or passed completely on the 490 // stack. LowerCall/LowerFormalArguments/LowerReturn must recognise these 491 // cases. 492 MCRegister Reg = State.AllocateReg(ArgGPRs); 493 if (!Reg) { 494 int64_t StackOffset = State.AllocateStack(8, Align(8)); 495 State.addLoc( 496 CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo)); 497 return false; 498 } 499 LocVT = MVT::i32; 500 State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 501 MCRegister HiReg = State.AllocateReg(ArgGPRs); 502 if (HiReg) { 503 State.addLoc( 504 CCValAssign::getCustomReg(ValNo, ValVT, HiReg, LocVT, LocInfo)); 505 } else { 506 int64_t StackOffset = State.AllocateStack(4, Align(4)); 507 State.addLoc( 508 CCValAssign::getCustomMem(ValNo, ValVT, StackOffset, LocVT, LocInfo)); 509 } 510 return false; 511 } 512 513 // Split arguments might be passed indirectly, so keep track of the pending 514 // values. Split vectors are passed via a mix of registers and indirectly, so 515 // treat them as we would any other argument. 516 if (ValVT.isScalarInteger() && (ArgFlags.isSplit() || !PendingLocs.empty())) { 517 LocVT = XLenVT; 518 LocInfo = CCValAssign::Indirect; 519 PendingLocs.push_back( 520 CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); 521 PendingArgFlags.push_back(ArgFlags); 522 if (!ArgFlags.isSplitEnd()) { 523 return false; 524 } 525 } 526 527 // If the split argument only had two elements, it should be passed directly 528 // in registers or on the stack. 529 if (ValVT.isScalarInteger() && ArgFlags.isSplitEnd() && 530 PendingLocs.size() <= 2) { 531 assert(PendingLocs.size() == 2 && "Unexpected PendingLocs.size()"); 532 // Apply the normal calling convention rules to the first half of the 533 // split argument. 534 CCValAssign VA = PendingLocs[0]; 535 ISD::ArgFlagsTy AF = PendingArgFlags[0]; 536 PendingLocs.clear(); 537 PendingArgFlags.clear(); 538 return CC_RISCVAssign2XLen( 539 XLen, State, VA, AF, ValNo, ValVT, LocVT, ArgFlags, 540 ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E); 541 } 542 543 // Allocate to a register if possible, or else a stack slot. 544 MCRegister Reg; 545 unsigned StoreSizeBytes = XLen / 8; 546 Align StackAlign = Align(XLen / 8); 547 548 if (ValVT.isVector() || ValVT.isRISCVVectorTuple()) { 549 Reg = allocateRVVReg(ValVT, ValNo, State, TLI); 550 if (Reg) { 551 // Fixed-length vectors are located in the corresponding scalable-vector 552 // container types. 553 if (ValVT.isFixedLengthVector()) { 554 LocVT = TLI.getContainerForFixedLengthVector(LocVT); 555 State.addLoc( 556 CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 557 return false; 558 } 559 } else { 560 // For return values, the vector must be passed fully via registers or 561 // via the stack. 562 // FIXME: The proposed vector ABI only mandates v8-v15 for return values, 563 // but we're using all of them. 564 if (IsRet) 565 return true; 566 // Try using a GPR to pass the address 567 if ((Reg = State.AllocateReg(ArgGPRs))) { 568 LocVT = XLenVT; 569 LocInfo = CCValAssign::Indirect; 570 } else if (ValVT.isScalableVector()) { 571 LocVT = XLenVT; 572 LocInfo = CCValAssign::Indirect; 573 } else { 574 StoreSizeBytes = ValVT.getStoreSize(); 575 // Align vectors to their element sizes, being careful for vXi1 576 // vectors. 577 StackAlign = MaybeAlign(ValVT.getScalarSizeInBits() / 8).valueOrOne(); 578 } 579 } 580 } else { 581 Reg = State.AllocateReg(ArgGPRs); 582 } 583 584 int64_t StackOffset = 585 Reg ? 0 : State.AllocateStack(StoreSizeBytes, StackAlign); 586 587 // If we reach this point and PendingLocs is non-empty, we must be at the 588 // end of a split argument that must be passed indirectly. 589 if (!PendingLocs.empty()) { 590 assert(ArgFlags.isSplitEnd() && "Expected ArgFlags.isSplitEnd()"); 591 assert(PendingLocs.size() > 2 && "Unexpected PendingLocs.size()"); 592 593 for (auto &It : PendingLocs) { 594 if (Reg) 595 It.convertToReg(Reg); 596 else 597 It.convertToMem(StackOffset); 598 State.addLoc(It); 599 } 600 PendingLocs.clear(); 601 PendingArgFlags.clear(); 602 return false; 603 } 604 605 assert(((ValVT.isFloatingPoint() && !ValVT.isVector()) || LocVT == XLenVT || 606 (TLI.getSubtarget().hasVInstructions() && 607 (ValVT.isVector() || ValVT.isRISCVVectorTuple()))) && 608 "Expected an XLenVT or vector types at this stage"); 609 610 if (Reg) { 611 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 612 return false; 613 } 614 615 State.addLoc(CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo)); 616 return false; 617 } 618 619 // FastCC has less than 1% performance improvement for some particular 620 // benchmark. But theoretically, it may have benefit for some cases. 621 bool llvm::CC_RISCV_FastCC(unsigned ValNo, MVT ValVT, MVT LocVT, 622 CCValAssign::LocInfo LocInfo, 623 ISD::ArgFlagsTy ArgFlags, CCState &State, 624 bool IsFixed, bool IsRet, Type *OrigTy) { 625 const MachineFunction &MF = State.getMachineFunction(); 626 const RISCVSubtarget &Subtarget = MF.getSubtarget<RISCVSubtarget>(); 627 const RISCVTargetLowering &TLI = *Subtarget.getTargetLowering(); 628 RISCVABI::ABI ABI = Subtarget.getTargetABI(); 629 630 if ((LocVT == MVT::f16 && Subtarget.hasStdExtZfhmin()) || 631 (LocVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin())) { 632 static const MCPhysReg FPR16List[] = { 633 RISCV::F10_H, RISCV::F11_H, RISCV::F12_H, RISCV::F13_H, RISCV::F14_H, 634 RISCV::F15_H, RISCV::F16_H, RISCV::F17_H, RISCV::F0_H, RISCV::F1_H, 635 RISCV::F2_H, RISCV::F3_H, RISCV::F4_H, RISCV::F5_H, RISCV::F6_H, 636 RISCV::F7_H, RISCV::F28_H, RISCV::F29_H, RISCV::F30_H, RISCV::F31_H}; 637 if (MCRegister Reg = State.AllocateReg(FPR16List)) { 638 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 639 return false; 640 } 641 } 642 643 if (LocVT == MVT::f32 && Subtarget.hasStdExtF()) { 644 static const MCPhysReg FPR32List[] = { 645 RISCV::F10_F, RISCV::F11_F, RISCV::F12_F, RISCV::F13_F, RISCV::F14_F, 646 RISCV::F15_F, RISCV::F16_F, RISCV::F17_F, RISCV::F0_F, RISCV::F1_F, 647 RISCV::F2_F, RISCV::F3_F, RISCV::F4_F, RISCV::F5_F, RISCV::F6_F, 648 RISCV::F7_F, RISCV::F28_F, RISCV::F29_F, RISCV::F30_F, RISCV::F31_F}; 649 if (MCRegister Reg = State.AllocateReg(FPR32List)) { 650 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 651 return false; 652 } 653 } 654 655 if (LocVT == MVT::f64 && Subtarget.hasStdExtD()) { 656 static const MCPhysReg FPR64List[] = { 657 RISCV::F10_D, RISCV::F11_D, RISCV::F12_D, RISCV::F13_D, RISCV::F14_D, 658 RISCV::F15_D, RISCV::F16_D, RISCV::F17_D, RISCV::F0_D, RISCV::F1_D, 659 RISCV::F2_D, RISCV::F3_D, RISCV::F4_D, RISCV::F5_D, RISCV::F6_D, 660 RISCV::F7_D, RISCV::F28_D, RISCV::F29_D, RISCV::F30_D, RISCV::F31_D}; 661 if (MCRegister Reg = State.AllocateReg(FPR64List)) { 662 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 663 return false; 664 } 665 } 666 667 MVT XLenVT = Subtarget.getXLenVT(); 668 669 // Check if there is an available GPRF16 before hitting the stack. 670 if ((LocVT == MVT::f16 && Subtarget.hasStdExtZhinxmin())) { 671 if (MCRegister Reg = State.AllocateReg(getFastCCArgGPRF16s(ABI))) { 672 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 673 return false; 674 } 675 } 676 677 // Check if there is an available GPRF32 before hitting the stack. 678 if (LocVT == MVT::f32 && Subtarget.hasStdExtZfinx()) { 679 if (MCRegister Reg = State.AllocateReg(getFastCCArgGPRF32s(ABI))) { 680 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 681 return false; 682 } 683 } 684 685 // Check if there is an available GPR before hitting the stack. 686 if (LocVT == MVT::f64 && Subtarget.is64Bit() && Subtarget.hasStdExtZdinx()) { 687 if (MCRegister Reg = State.AllocateReg(getFastCCArgGPRs(ABI))) { 688 if (LocVT.getSizeInBits() != Subtarget.getXLen()) { 689 LocVT = XLenVT; 690 State.addLoc( 691 CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 692 return false; 693 } 694 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 695 return false; 696 } 697 } 698 699 ArrayRef<MCPhysReg> ArgGPRs = getFastCCArgGPRs(ABI); 700 701 if (LocVT.isVector()) { 702 if (MCRegister Reg = allocateRVVReg(ValVT, ValNo, State, TLI)) { 703 // Fixed-length vectors are located in the corresponding scalable-vector 704 // container types. 705 if (LocVT.isFixedLengthVector()) { 706 LocVT = TLI.getContainerForFixedLengthVector(LocVT); 707 State.addLoc( 708 CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 709 return false; 710 } 711 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 712 return false; 713 } 714 715 // Pass scalable vectors indirectly. Pass fixed vectors indirectly if we 716 // have a free GPR. 717 if (LocVT.isScalableVector() || 718 State.getFirstUnallocated(ArgGPRs) != ArgGPRs.size()) { 719 LocInfo = CCValAssign::Indirect; 720 LocVT = XLenVT; 721 } 722 } 723 724 if (LocVT == XLenVT) { 725 if (MCRegister Reg = State.AllocateReg(getFastCCArgGPRs(ABI))) { 726 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 727 return false; 728 } 729 } 730 731 if (LocVT == XLenVT || LocVT == MVT::f16 || LocVT == MVT::bf16 || 732 LocVT == MVT::f32 || LocVT == MVT::f64 || LocVT.isFixedLengthVector()) { 733 Align StackAlign = MaybeAlign(ValVT.getScalarSizeInBits() / 8).valueOrOne(); 734 int64_t Offset = State.AllocateStack(LocVT.getStoreSize(), StackAlign); 735 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); 736 return false; 737 } 738 739 return true; // CC didn't match. 740 } 741 742 bool llvm::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, 743 CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, 744 CCState &State) { 745 if (ArgFlags.isNest()) { 746 report_fatal_error( 747 "Attribute 'nest' is not supported in GHC calling convention"); 748 } 749 750 static const MCPhysReg GPRList[] = { 751 RISCV::X9, RISCV::X18, RISCV::X19, RISCV::X20, RISCV::X21, RISCV::X22, 752 RISCV::X23, RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27}; 753 754 if (LocVT == MVT::i32 || LocVT == MVT::i64) { 755 // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, R6, R7, SpLim 756 // s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 757 if (MCRegister Reg = State.AllocateReg(GPRList)) { 758 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 759 return false; 760 } 761 } 762 763 const RISCVSubtarget &Subtarget = 764 State.getMachineFunction().getSubtarget<RISCVSubtarget>(); 765 766 if (LocVT == MVT::f32 && Subtarget.hasStdExtF()) { 767 // Pass in STG registers: F1, ..., F6 768 // fs0 ... fs5 769 static const MCPhysReg FPR32List[] = {RISCV::F8_F, RISCV::F9_F, 770 RISCV::F18_F, RISCV::F19_F, 771 RISCV::F20_F, RISCV::F21_F}; 772 if (MCRegister Reg = State.AllocateReg(FPR32List)) { 773 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 774 return false; 775 } 776 } 777 778 if (LocVT == MVT::f64 && Subtarget.hasStdExtD()) { 779 // Pass in STG registers: D1, ..., D6 780 // fs6 ... fs11 781 static const MCPhysReg FPR64List[] = {RISCV::F22_D, RISCV::F23_D, 782 RISCV::F24_D, RISCV::F25_D, 783 RISCV::F26_D, RISCV::F27_D}; 784 if (MCRegister Reg = State.AllocateReg(FPR64List)) { 785 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 786 return false; 787 } 788 } 789 790 if (LocVT == MVT::f32 && Subtarget.hasStdExtZfinx()) { 791 static const MCPhysReg GPR32List[] = { 792 RISCV::X9_W, RISCV::X18_W, RISCV::X19_W, RISCV::X20_W, 793 RISCV::X21_W, RISCV::X22_W, RISCV::X23_W, RISCV::X24_W, 794 RISCV::X25_W, RISCV::X26_W, RISCV::X27_W}; 795 if (MCRegister Reg = State.AllocateReg(GPR32List)) { 796 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 797 return false; 798 } 799 } 800 801 if (LocVT == MVT::f64 && Subtarget.hasStdExtZdinx() && Subtarget.is64Bit()) { 802 if (MCRegister Reg = State.AllocateReg(GPRList)) { 803 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 804 return false; 805 } 806 } 807 808 report_fatal_error("No registers left in GHC calling convention"); 809 return true; 810 } 811