1 //===-- PPCCallingConv.h - --------------------------------------*- 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 static bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 25 CCValAssign::LocInfo &LocInfo, 26 ISD::ArgFlagsTy &ArgFlags, 27 CCState &State) { 28 return true; 29 } 30 31 static bool CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT, 32 MVT &LocVT, 33 CCValAssign::LocInfo &LocInfo, 34 ISD::ArgFlagsTy &ArgFlags, 35 CCState &State) { 36 static const MCPhysReg ArgRegs[] = { 37 PPC::R3, PPC::R4, PPC::R5, PPC::R6, 38 PPC::R7, PPC::R8, PPC::R9, PPC::R10, 39 }; 40 const unsigned NumArgRegs = array_lengthof(ArgRegs); 41 42 unsigned RegNum = State.getFirstUnallocated(ArgRegs); 43 44 // Skip one register if the first unallocated register has an even register 45 // number and there are still argument registers available which have not been 46 // allocated yet. RegNum is actually an index into ArgRegs, which means we 47 // need to skip a register if RegNum is odd. 48 if (RegNum != NumArgRegs && RegNum % 2 == 1) { 49 State.AllocateReg(ArgRegs[RegNum]); 50 } 51 52 // Always return false here, as this function only makes sure that the first 53 // unallocated register has an odd register number and does not actually 54 // allocate a register for the current argument. 55 return false; 56 } 57 58 static bool CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128( 59 unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, 60 ISD::ArgFlagsTy &ArgFlags, CCState &State) { 61 static const MCPhysReg ArgRegs[] = { 62 PPC::R3, PPC::R4, PPC::R5, PPC::R6, 63 PPC::R7, PPC::R8, PPC::R9, PPC::R10, 64 }; 65 const unsigned NumArgRegs = array_lengthof(ArgRegs); 66 67 unsigned RegNum = State.getFirstUnallocated(ArgRegs); 68 int RegsLeft = NumArgRegs - RegNum; 69 70 // Skip if there is not enough registers left for long double type (4 gpr regs 71 // in soft float mode) and put long double argument on the stack. 72 if (RegNum != NumArgRegs && RegsLeft < 4) { 73 for (int i = 0; i < RegsLeft; i++) { 74 State.AllocateReg(ArgRegs[RegNum + i]); 75 } 76 } 77 78 return false; 79 } 80 81 static bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT, 82 MVT &LocVT, 83 CCValAssign::LocInfo &LocInfo, 84 ISD::ArgFlagsTy &ArgFlags, 85 CCState &State) { 86 static const MCPhysReg ArgRegs[] = { 87 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, 88 PPC::F8 89 }; 90 91 const unsigned NumArgRegs = array_lengthof(ArgRegs); 92 93 unsigned RegNum = State.getFirstUnallocated(ArgRegs); 94 95 // If there is only one Floating-point register left we need to put both f64 96 // values of a split ppc_fp128 value on the stack. 97 if (RegNum != NumArgRegs && ArgRegs[RegNum] == PPC::F8) { 98 State.AllocateReg(ArgRegs[RegNum]); 99 } 100 101 // Always return false here, as this function only makes sure that the two f64 102 // values a ppc_fp128 value is split into are both passed in registers or both 103 // passed on the stack and does not actually allocate a register for the 104 // current argument. 105 return false; 106 } 107 108 #include "PPCGenCallingConv.inc" 109