LLVM  10.0.0svn
PPCCallingConv.cpp
Go to the documentation of this file.
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 &,
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 
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 // Split F64 arguments into two 32-bit consecutive registers.
109 static bool CC_PPC32_SPE_CustomSplitFP64(unsigned &ValNo, MVT &ValVT,
110  MVT &LocVT,
111  CCValAssign::LocInfo &LocInfo,
112  ISD::ArgFlagsTy &ArgFlags,
113  CCState &State) {
114  static const MCPhysReg HiRegList[] = { PPC::R3, PPC::R5, PPC::R7, PPC::R9 };
115  static const MCPhysReg LoRegList[] = { PPC::R4, PPC::R6, PPC::R8, PPC::R10 };
116 
117  // Try to get the first register.
118  unsigned Reg = State.AllocateReg(HiRegList);
119  if (!Reg)
120  return false;
121 
122  unsigned i;
123  for (i = 0; i < sizeof(HiRegList) / sizeof(HiRegList[0]); ++i)
124  if (HiRegList[i] == Reg)
125  break;
126 
127  unsigned T = State.AllocateReg(LoRegList[i]);
128  (void)T;
129  assert(T == LoRegList[i] && "Could not allocate register");
130 
131  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
132  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
133  LocVT, LocInfo));
134  return true;
135 }
136 
137 // Same as above, but for return values, so only allocate for R3 and R4
138 static bool CC_PPC32_SPE_RetF64(unsigned &ValNo, MVT &ValVT,
139  MVT &LocVT,
140  CCValAssign::LocInfo &LocInfo,
141  ISD::ArgFlagsTy &ArgFlags,
142  CCState &State) {
143  static const MCPhysReg HiRegList[] = { PPC::R3 };
144  static const MCPhysReg LoRegList[] = { PPC::R4 };
145 
146  // Try to get the first register.
147  unsigned Reg = State.AllocateReg(HiRegList, LoRegList);
148  if (!Reg)
149  return false;
150 
151  unsigned i;
152  for (i = 0; i < sizeof(HiRegList) / sizeof(HiRegList[0]); ++i)
153  if (HiRegList[i] == Reg)
154  break;
155 
156  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
157  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
158  LocVT, LocInfo));
159  return true;
160 }
161 
162 #include "PPCGenCallingConv.inc"
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set, or Regs.size() if they are all allocated.
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
#define R4(n)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
unsigned Reg
static bool CC_PPC32_SPE_RetF64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static bool CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
void addLoc(const CCValAssign &V)
static bool CC_PPC32_SPE_CustomSplitFP64(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static bool CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:19
Machine Value Type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CCState - This class holds information needed while lowering arguments and return values...
#define R6(n)
static bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
bool CC_PPC_AnyReg_Error(unsigned &, MVT &, MVT &, CCValAssign::LocInfo &, ISD::ArgFlagsTy &, CCState &)
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:1023
static bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned AllocateReg(unsigned Reg)
AllocateReg - Attempt to allocate one register.