LLVM: lib/Target/AArch64/AArch64CallingConvention.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

20using namespace llvm;

21

22static const MCPhysReg XRegList[] = {AArch64::X0, AArch64::X1, AArch64::X2,

23 AArch64::X3, AArch64::X4, AArch64::X5,

24 AArch64::X6, AArch64::X7};

25static const MCPhysReg HRegList[] = {AArch64::H0, AArch64::H1, AArch64::H2,

26 AArch64::H3, AArch64::H4, AArch64::H5,

27 AArch64::H6, AArch64::H7};

28static const MCPhysReg SRegList[] = {AArch64::S0, AArch64::S1, AArch64::S2,

29 AArch64::S3, AArch64::S4, AArch64::S5,

30 AArch64::S6, AArch64::S7};

31static const MCPhysReg DRegList[] = {AArch64::D0, AArch64::D1, AArch64::D2,

32 AArch64::D3, AArch64::D4, AArch64::D5,

33 AArch64::D6, AArch64::D7};

34static const MCPhysReg QRegList[] = {AArch64::Q0, AArch64::Q1, AArch64::Q2,

35 AArch64::Q3, AArch64::Q4, AArch64::Q5,

36 AArch64::Q6, AArch64::Q7};

37static const MCPhysReg ZRegList[] = {AArch64::Z0, AArch64::Z1, AArch64::Z2,

38 AArch64::Z3, AArch64::Z4, AArch64::Z5,

39 AArch64::Z6, AArch64::Z7};

40static const MCPhysReg PRegList[] = {AArch64::P0, AArch64::P1, AArch64::P2,

41 AArch64::P3};

42

50

51

52

53

56

57

58

59

60

61

62

63 bool ZRegsAllocated[8];

64 for (int I = 0; I < 8; I++) {

67 }

68

69 bool PRegsAllocated[4];

70 for (int I = 0; I < 4; I++) {

73 }

74

75 auto &It = PendingMembers[0];

78 if (AssignFn(It.getValNo(), It.getValVT(), It.getValVT(), CCValAssign::Full,

79 ArgFlags, State))

81

82

85

86

87

88 for (int I = 0; I < 8; I++)

89 if (!ZRegsAllocated[I])

91 for (int I = 0; I < 4; I++)

92 if (!PRegsAllocated[I])

94

95

96 PendingMembers.clear();

97 return true;

98 }

99

101 for (auto &It : PendingMembers) {

104 SlotAlign = Align(1);

105 }

106

107

108 PendingMembers.clear();

109 return true;

110}

111

112

113

118

119

120

123

125 return true;

126

128}

129

130

131

132

139

140

141

143 if (LocVT.SimpleTy == MVT::i64 || (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32))

145 else if (LocVT.SimpleTy == MVT::f16)

154

155 if (LocVT == MVT::nxv1i1 || LocVT == MVT::nxv2i1 || LocVT == MVT::nxv4i1 ||

156 LocVT == MVT::nxv8i1 || LocVT == MVT::nxv16i1 ||

157 LocVT == MVT::aarch64svcount)

159 else

161 } else {

162

163 return false;

164 }

165

167

168

169

172

174 return true;

175

176

177

178 unsigned EltsPerReg = (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32) ? 2 : 1;

180 RegList, alignTo(PendingMembers.size(), EltsPerReg) / EltsPerReg);

181 if (!RegResult.empty() && EltsPerReg == 1) {

182 for (const auto &[It, Reg] : zip(PendingMembers, RegResult)) {

183 It.convertToReg(Reg);

185 }

186 PendingMembers.clear();

187 return true;

188 } else if (!RegResult.empty()) {

189 assert(EltsPerReg == 2 && "unexpected ABI");

190 bool UseHigh = false;

192 unsigned RegIdx = 0;

193 for (auto &It : PendingMembers) {

196 RegResult[RegIdx], MVT::i64, Info));

197 UseHigh = !UseHigh;

198 if (!UseHigh)

199 ++RegIdx;

200 }

201 PendingMembers.clear();

202 return true;

203 }

204

206

207 for (auto Reg : RegList)

209 }

210

213 assert(StackAlign && "data layout string is missing stack alignment");

215 Align SlotAlign = std::min(MemAlign, *StackAlign);

217 SlotAlign = std::max(SlotAlign, Align(8));

218

219 return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign);

220}

221

222

223

224#include "AArch64GenCallingConv.inc"

static bool finishStackBlock(SmallVectorImpl< CCValAssign > &PendingMembers, MVT LocVT, ISD::ArgFlagsTy &ArgFlags, CCState &State, Align SlotAlign)

static const MCPhysReg XRegList[]

static const MCPhysReg SRegList[]

static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

Given an [N x Ty] block, it should be passed in a consecutive sequence of registers.

static const MCPhysReg ZRegList[]

static const MCPhysReg DRegList[]

static const MCPhysReg HRegList[]

static const MCPhysReg QRegList[]

static const MCPhysReg PRegList[]

static bool CC_AArch64_Custom_Stack_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

The Darwin variadic PCS places anonymous arguments in 8-byte stack slots.

Analysis containing CSE Info

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

bool isTargetDarwin() const

bool isTargetILP32() const

const AArch64TargetLowering * getTargetLowering() const override

bool isTargetMachO() const

CCAssignFn * CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const

Selects the correct CCAssignFn for a given CallingConvention value.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

bool empty() const

empty - Check if the array is empty.

CCState - This class holds information needed while lowering arguments and return values.

MachineFunction & getMachineFunction() const

CallingConv::ID getCallingConv() const

MCRegister AllocateReg(MCPhysReg Reg)

AllocateReg - Attempt to allocate one register.

ArrayRef< MCPhysReg > AllocateRegBlock(ArrayRef< MCPhysReg > Regs, unsigned RegsRequired)

Attempt to allocate a block of RegsRequired consecutive registers.

int64_t AllocateStack(unsigned Size, Align Alignment)

AllocateStack - Allocate a chunk of stack space with the specified size and alignment.

void DeallocateReg(MCPhysReg Reg)

SmallVectorImpl< CCValAssign > & getPendingLocs()

bool isAllocated(MCRegister Reg) const

isAllocated - Return true if the specified register (or an alias) is allocated.

void addLoc(const CCValAssign &V)

static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)

static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)

MaybeAlign getStackAlignment() const

Returns the natural stack alignment, or MaybeAlign() if one wasn't specified.

bool is128BitVector() const

Return true if this is a 128-bit vector type.

bool isScalableVector() const

Return true if this is a vector value type where the runtime length is machine dependent.

bool is32BitVector() const

Return true if this is a 32-bit vector type.

TypeSize getSizeInBits() const

Returns the size of the specified MVT in bits.

bool is64BitVector() const

Return true if this is a 64-bit vector type.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

const DataLayout & getDataLayout() const

Return the DataLayout attached to the Module associated to this MF.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

This is an optimization pass for GlobalISel generic memory operations.

detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)

zip iterator for two or more iteratable types.

bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)

CCAssignFn - This function assigns a location for Val, updating State to reflect the change.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

This struct is a compact representation of a valid (non-zero power of two) alignment.

void setInConsecutiveRegs(bool Flag=true)

bool isInConsecutiveRegsLast() const

Align getNonZeroMemAlign() const

void setInConsecutiveRegsLast(bool Flag=true)

This struct is a compact representation of a valid (power of two) or undefined (0) alignment.