LLVM  12.0.0git
AArch64CallingConvention.cpp
Go to the documentation of this file.
1 //=== AArch64CallingConvention.cpp - AArch64 CC impl ------------*- 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 // This file contains the table-generated and custom routines for the AArch64
10 // Calling Convention.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "AArch64.h"
16 #include "AArch64InstrInfo.h"
17 #include "AArch64Subtarget.h"
20 #include "llvm/IR/CallingConv.h"
21 using namespace llvm;
22 
23 static const MCPhysReg XRegList[] = {AArch64::X0, AArch64::X1, AArch64::X2,
24  AArch64::X3, AArch64::X4, AArch64::X5,
25  AArch64::X6, AArch64::X7};
26 static const MCPhysReg HRegList[] = {AArch64::H0, AArch64::H1, AArch64::H2,
27  AArch64::H3, AArch64::H4, AArch64::H5,
28  AArch64::H6, AArch64::H7};
29 static const MCPhysReg SRegList[] = {AArch64::S0, AArch64::S1, AArch64::S2,
30  AArch64::S3, AArch64::S4, AArch64::S5,
31  AArch64::S6, AArch64::S7};
32 static const MCPhysReg DRegList[] = {AArch64::D0, AArch64::D1, AArch64::D2,
33  AArch64::D3, AArch64::D4, AArch64::D5,
34  AArch64::D6, AArch64::D7};
35 static const MCPhysReg QRegList[] = {AArch64::Q0, AArch64::Q1, AArch64::Q2,
36  AArch64::Q3, AArch64::Q4, AArch64::Q5,
37  AArch64::Q6, AArch64::Q7};
38 
39 static bool finishStackBlock(SmallVectorImpl<CCValAssign> &PendingMembers,
40  MVT LocVT, ISD::ArgFlagsTy &ArgFlags,
41  CCState &State, Align SlotAlign) {
42  unsigned Size = LocVT.getSizeInBits() / 8;
43  const Align StackAlign =
45  const Align OrigAlign = ArgFlags.getNonZeroOrigAlign();
46  const Align Alignment = std::min(OrigAlign, StackAlign);
47 
48  for (auto &It : PendingMembers) {
49  It.convertToMem(State.AllocateStack(Size, std::max(Alignment, SlotAlign)));
50  State.addLoc(It);
51  SlotAlign = Align(1);
52  }
53 
54  // All pending members have now been allocated
55  PendingMembers.clear();
56  return true;
57 }
58 
59 /// The Darwin variadic PCS places anonymous arguments in 8-byte stack slots. An
60 /// [N x Ty] type must still be contiguous in memory though.
62  unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
63  ISD::ArgFlagsTy &ArgFlags, CCState &State) {
64  SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
65 
66  // Add the argument to the list to be allocated once we know the size of the
67  // block.
68  PendingMembers.push_back(
69  CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
70 
71  if (!ArgFlags.isInConsecutiveRegsLast())
72  return true;
73 
74  return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, Align(8));
75 }
76 
77 /// Given an [N x Ty] block, it should be passed in a consecutive sequence of
78 /// registers. If no such sequence is available, mark the rest of the registers
79 /// of that type as used and place the argument on the stack.
80 static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
81  CCValAssign::LocInfo &LocInfo,
82  ISD::ArgFlagsTy &ArgFlags, CCState &State) {
83  const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(
85  bool IsDarwinILP32 = Subtarget.isTargetILP32() && Subtarget.isTargetMachO();
86 
87  // Try to allocate a contiguous block of registers, each of the correct
88  // size to hold one member.
89  ArrayRef<MCPhysReg> RegList;
90  if (LocVT.SimpleTy == MVT::i64 || (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32))
91  RegList = XRegList;
92  else if (LocVT.SimpleTy == MVT::f16)
93  RegList = HRegList;
94  else if (LocVT.SimpleTy == MVT::f32 || LocVT.is32BitVector())
95  RegList = SRegList;
96  else if (LocVT.SimpleTy == MVT::f64 || LocVT.is64BitVector())
97  RegList = DRegList;
98  else if (LocVT.SimpleTy == MVT::f128 || LocVT.is128BitVector())
99  RegList = QRegList;
100  else {
101  // Not an array we want to split up after all.
102  return false;
103  }
104 
105  SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
106 
107  // Add the argument to the list to be allocated once we know the size of the
108  // block.
109  PendingMembers.push_back(
110  CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
111 
112  if (!ArgFlags.isInConsecutiveRegsLast())
113  return true;
114 
115  // [N x i32] arguments get packed into x-registers on Darwin's arm64_32
116  // because that's how the armv7k Clang front-end emits small structs.
117  unsigned EltsPerReg = (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32) ? 2 : 1;
118  unsigned RegResult = State.AllocateRegBlock(
119  RegList, alignTo(PendingMembers.size(), EltsPerReg) / EltsPerReg);
120  if (RegResult && EltsPerReg == 1) {
121  for (auto &It : PendingMembers) {
122  It.convertToReg(RegResult);
123  State.addLoc(It);
124  ++RegResult;
125  }
126  PendingMembers.clear();
127  return true;
128  } else if (RegResult) {
129  assert(EltsPerReg == 2 && "unexpected ABI");
130  bool UseHigh = false;
132  for (auto &It : PendingMembers) {
133  Info = UseHigh ? CCValAssign::AExtUpper : CCValAssign::ZExt;
134  State.addLoc(CCValAssign::getReg(It.getValNo(), MVT::i32, RegResult,
135  MVT::i64, Info));
136  UseHigh = !UseHigh;
137  if (!UseHigh)
138  ++RegResult;
139  }
140  PendingMembers.clear();
141  return true;
142  }
143 
144  // Mark all regs in the class as unavailable
145  for (auto Reg : RegList)
146  State.AllocateReg(Reg);
147 
148  const Align SlotAlign = Subtarget.isTargetDarwin() ? Align(1) : Align(8);
149 
150  return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign);
151 }
152 
153 // TableGen provides definitions of the calling convention analysis entry
154 // points.
155 #include "AArch64GenCallingConv.inc"
static const MCPhysReg XRegList[]
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static const MCPhysReg HRegList[]
Align getStackAlignment() const
Definition: DataLayout.h:269
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
unsigned Reg
Align getNonZeroOrigAlign() const
MachineFunction & getMachineFunction() const
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.
static const MCPhysReg DRegList[]
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
void addLoc(const CCValAssign &V)
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
SimpleValueType SimpleTy
static const MCPhysReg QRegList[]
bool is64BitVector() const
Return true if this is a 64-bit vector type.
SmallVectorImpl< CCValAssign > & getPendingLocs()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
Analysis containing CSE Info
Definition: CSEInfo.cpp:25
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:19
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
bool is128BitVector() const
Return true if this is a 128-bit vector type.
Machine Value Type.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
unsigned AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:305
static bool finishStackBlock(SmallVectorImpl< CCValAssign > &PendingMembers, MVT LocVT, ISD::ArgFlagsTy &ArgFlags, CCState &State, Align SlotAlign)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
CCState - This class holds information needed while lowering arguments and return values...
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:350
MCPhysReg AllocateRegBlock(ArrayRef< MCPhysReg > Regs, unsigned RegsRequired)
AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive registers.
bool is32BitVector() const
Return true if this is a 32-bit vector type.
static const MCPhysReg SRegList[]
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:158
bool isInConsecutiveRegsLast() const
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.