LLVM  10.0.0svn
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, unsigned SlotAlign) {
42  unsigned Size = LocVT.getSizeInBits() / 8;
43  unsigned StackAlign =
45  unsigned Align = std::min(ArgFlags.getOrigAlign(), StackAlign);
46 
47  for (auto &It : PendingMembers) {
48  It.convertToMem(State.AllocateStack(Size, std::max(Align, SlotAlign)));
49  State.addLoc(It);
50  SlotAlign = 1;
51  }
52 
53  // All pending members have now been allocated
54  PendingMembers.clear();
55  return true;
56 }
57 
58 /// The Darwin variadic PCS places anonymous arguments in 8-byte stack slots. An
59 /// [N x Ty] type must still be contiguous in memory though.
61  unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
62  ISD::ArgFlagsTy &ArgFlags, CCState &State) {
63  SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
64 
65  // Add the argument to the list to be allocated once we know the size of the
66  // block.
67  PendingMembers.push_back(
68  CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
69 
70  if (!ArgFlags.isInConsecutiveRegsLast())
71  return true;
72 
73  return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, 8);
74 }
75 
76 /// Given an [N x Ty] block, it should be passed in a consecutive sequence of
77 /// registers. If no such sequence is available, mark the rest of the registers
78 /// of that type as used and place the argument on the stack.
79 static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
80  CCValAssign::LocInfo &LocInfo,
81  ISD::ArgFlagsTy &ArgFlags, CCState &State) {
82  const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(
84  bool IsDarwinILP32 = Subtarget.isTargetILP32() && Subtarget.isTargetMachO();
85 
86  // Try to allocate a contiguous block of registers, each of the correct
87  // size to hold one member.
88  ArrayRef<MCPhysReg> RegList;
89  if (LocVT.SimpleTy == MVT::i64 || (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32))
90  RegList = XRegList;
91  else if (LocVT.SimpleTy == MVT::f16)
92  RegList = HRegList;
93  else if (LocVT.SimpleTy == MVT::f32 || LocVT.is32BitVector())
94  RegList = SRegList;
95  else if (LocVT.SimpleTy == MVT::f64 || LocVT.is64BitVector())
96  RegList = DRegList;
97  else if (LocVT.SimpleTy == MVT::f128 || LocVT.is128BitVector())
98  RegList = QRegList;
99  else {
100  // Not an array we want to split up after all.
101  return false;
102  }
103 
104  SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
105 
106  // Add the argument to the list to be allocated once we know the size of the
107  // block.
108  PendingMembers.push_back(
109  CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
110 
111  if (!ArgFlags.isInConsecutiveRegsLast())
112  return true;
113 
114  // [N x i32] arguments get packed into x-registers on Darwin's arm64_32
115  // because that's how the armv7k Clang front-end emits small structs.
116  unsigned EltsPerReg = (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32) ? 2 : 1;
117  unsigned RegResult = State.AllocateRegBlock(
118  RegList, alignTo(PendingMembers.size(), EltsPerReg) / EltsPerReg);
119  if (RegResult && EltsPerReg == 1) {
120  for (auto &It : PendingMembers) {
121  It.convertToReg(RegResult);
122  State.addLoc(It);
123  ++RegResult;
124  }
125  PendingMembers.clear();
126  return true;
127  } else if (RegResult) {
128  assert(EltsPerReg == 2 && "unexpected ABI");
129  bool UseHigh = false;
131  for (auto &It : PendingMembers) {
132  Info = UseHigh ? CCValAssign::AExtUpper : CCValAssign::ZExt;
133  State.addLoc(CCValAssign::getReg(It.getValNo(), MVT::i32, RegResult,
134  MVT::i64, Info));
135  UseHigh = !UseHigh;
136  if (!UseHigh)
137  ++RegResult;
138  }
139  PendingMembers.clear();
140  return true;
141  }
142 
143  // Mark all regs in the class as unavailable
144  for (auto Reg : RegList)
145  State.AllocateReg(Reg);
146 
147  unsigned SlotAlign = Subtarget.isTargetDarwin() ? 1 : 8;
148 
149  return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign);
150 }
151 
152 // TableGen provides definitions of the calling convention analysis entry
153 // points.
154 #include "AArch64GenCallingConv.inc"
static const MCPhysReg XRegList[]
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static const MCPhysReg HRegList[]
unsigned Reg
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:41
void addLoc(const CCValAssign &V)
SimpleValueType SimpleTy
static const MCPhysReg QRegList[]
static bool finishStackBlock(SmallVectorImpl< CCValAssign > &PendingMembers, MVT LocVT, ISD::ArgFlagsTy &ArgFlags, CCState &State, unsigned SlotAlign)
bool is64BitVector() const
Return true if this is a 64-bit vector type.
unsigned getSizeInBits() const
SmallVectorImpl< CCValAssign > & getPendingLocs()
unsigned getStackAlignment() const
Definition: DataLayout.h:269
Analysis containing CSE Info
Definition: CSEInfo.cpp:20
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.
unsigned getOrigAlign() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
size_t size() const
Definition: SmallVector.h:52
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:40
CCState - This class holds information needed while lowering arguments and return values...
unsigned 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:126
unsigned AllocateStack(unsigned Size, unsigned Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
bool isInConsecutiveRegsLast() const
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned AllocateReg(unsigned Reg)
AllocateReg - Attempt to allocate one register.
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.