LLVM  4.0.0
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"
22 #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
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
unsigned getStackAlignment() const
Definition: DataLayout.h:256
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
unsigned getSizeInBits() const
bool is32BitVector() const
is32BitVector - Return true if this is a 32-bit vector type.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:32
void addLoc(const CCValAssign &V)
Reg
All possible values of the reg field in the ModR/M byte.
SimpleValueType SimpleTy
SmallVectorImpl< llvm::CCValAssign > & getPendingLocs()
MachineFunction & getMachineFunction() const
bool isInConsecutiveRegsLast() const
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
MVT - Machine Value Type.
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 is64BitVector() const
is64BitVector - Return true if this is a 64-bit vector type.
bool is128BitVector() const
is128BitVector - Return true if this is a 128-bit vector type.
bool isTargetDarwin() const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
static const MCPhysReg QRegList[]
static const MCPhysReg DRegList[]
unsigned getOrigAlign() const
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[]