LLVM  6.0.0svn
AArch64CallingConvention.h
Go to the documentation of this file.
1 //=== AArch64CallingConv.h - Custom Calling Convention Routines -*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the custom routines for the AArch64 Calling Convention
11 // that aren't done by tablegen.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64CALLINGCONVENTION_H
16 #define LLVM_LIB_TARGET_AARCH64_AARCH64CALLINGCONVENTION_H
17 
18 #include "AArch64.h"
19 #include "AArch64InstrInfo.h"
20 #include "AArch64Subtarget.h"
23 #include "llvm/IR/CallingConv.h"
24 
25 namespace {
26 using namespace llvm;
27 
28 static const MCPhysReg XRegList[] = {AArch64::X0, AArch64::X1, AArch64::X2,
29  AArch64::X3, AArch64::X4, AArch64::X5,
30  AArch64::X6, AArch64::X7};
31 static const MCPhysReg HRegList[] = {AArch64::H0, AArch64::H1, AArch64::H2,
32  AArch64::H3, AArch64::H4, AArch64::H5,
33  AArch64::H6, AArch64::H7};
34 static const MCPhysReg SRegList[] = {AArch64::S0, AArch64::S1, AArch64::S2,
35  AArch64::S3, AArch64::S4, AArch64::S5,
36  AArch64::S6, AArch64::S7};
37 static const MCPhysReg DRegList[] = {AArch64::D0, AArch64::D1, AArch64::D2,
38  AArch64::D3, AArch64::D4, AArch64::D5,
39  AArch64::D6, AArch64::D7};
40 static const MCPhysReg QRegList[] = {AArch64::Q0, AArch64::Q1, AArch64::Q2,
41  AArch64::Q3, AArch64::Q4, AArch64::Q5,
42  AArch64::Q6, AArch64::Q7};
43 
44 static bool finishStackBlock(SmallVectorImpl<CCValAssign> &PendingMembers,
45  MVT LocVT, ISD::ArgFlagsTy &ArgFlags,
46  CCState &State, unsigned SlotAlign) {
47  unsigned Size = LocVT.getSizeInBits() / 8;
48  unsigned StackAlign =
50  unsigned Align = std::min(ArgFlags.getOrigAlign(), StackAlign);
51 
52  for (auto &It : PendingMembers) {
53  It.convertToMem(State.AllocateStack(Size, std::max(Align, SlotAlign)));
54  State.addLoc(It);
55  SlotAlign = 1;
56  }
57 
58  // All pending members have now been allocated
59  PendingMembers.clear();
60  return true;
61 }
62 
63 /// The Darwin variadic PCS places anonymous arguments in 8-byte stack slots. An
64 /// [N x Ty] type must still be contiguous in memory though.
65 static bool CC_AArch64_Custom_Stack_Block(
66  unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
67  ISD::ArgFlagsTy &ArgFlags, CCState &State) {
68  SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
69 
70  // Add the argument to the list to be allocated once we know the size of the
71  // block.
72  PendingMembers.push_back(
73  CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
74 
75  if (!ArgFlags.isInConsecutiveRegsLast())
76  return true;
77 
78  return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, 8);
79 }
80 
81 /// Given an [N x Ty] block, it should be passed in a consecutive sequence of
82 /// registers. If no such sequence is available, mark the rest of the registers
83 /// of that type as used and place the argument on the stack.
84 static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
85  CCValAssign::LocInfo &LocInfo,
86  ISD::ArgFlagsTy &ArgFlags, CCState &State) {
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)
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  unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
116  if (RegResult) {
117  for (auto &It : PendingMembers) {
118  It.convertToReg(RegResult);
119  State.addLoc(It);
120  ++RegResult;
121  }
122  PendingMembers.clear();
123  return true;
124  }
125 
126  // Mark all regs in the class as unavailable
127  for (auto Reg : RegList)
128  State.AllocateReg(Reg);
129 
130  const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(
131  State.getMachineFunction().getSubtarget());
132  unsigned SlotAlign = Subtarget.isTargetDarwin() ? 1 : 8;
133 
134  return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign);
135 }
136 
137 }
138 
139 #endif
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
MachineFunction & getMachineFunction() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
void addLoc(const CCValAssign &V)
Reg
All possible values of the reg field in the ModR/M byte.
SimpleValueType SimpleTy
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:252
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...
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.
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.
bool isInConsecutiveRegsLast() const
static const MCPhysReg QRegList[]
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
static const MCPhysReg DRegList[]
unsigned AllocateReg(unsigned Reg)
AllocateReg - Attempt to allocate one register.
unsigned AllocateStack(unsigned Size, unsigned Align)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
static const MCPhysReg SRegList[]