LLVM  3.7.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 uint16_t XRegList[] = {AArch64::X0, AArch64::X1, AArch64::X2,
29  AArch64::X3, AArch64::X4, AArch64::X5,
30  AArch64::X6, AArch64::X7};
31 static const uint16_t HRegList[] = {AArch64::H0, AArch64::H1, AArch64::H2,
32  AArch64::H3, AArch64::H4, AArch64::H5,
33  AArch64::H6, AArch64::H7};
34 static const uint16_t SRegList[] = {AArch64::S0, AArch64::S1, AArch64::S2,
35  AArch64::S3, AArch64::S4, AArch64::S5,
36  AArch64::S6, AArch64::S7};
37 static const uint16_t DRegList[] = {AArch64::D0, AArch64::D1, AArch64::D2,
38  AArch64::D3, AArch64::D4, AArch64::D5,
39  AArch64::D6, AArch64::D7};
40 static const uint16_t 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 = State.getMachineFunction()
49  .getTarget()
50  .getDataLayout()
52  unsigned Align = std::min(ArgFlags.getOrigAlign(), StackAlign);
53 
54  for (auto &It : PendingMembers) {
55  It.convertToMem(State.AllocateStack(Size, std::max(Align, SlotAlign)));
56  State.addLoc(It);
57  SlotAlign = 1;
58  }
59 
60  // All pending members have now been allocated
61  PendingMembers.clear();
62  return true;
63 }
64 
65 /// The Darwin variadic PCS places anonymous arguments in 8-byte stack slots. An
66 /// [N x Ty] type must still be contiguous in memory though.
67 static bool CC_AArch64_Custom_Stack_Block(
68  unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
69  ISD::ArgFlagsTy &ArgFlags, CCState &State) {
70  SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
71 
72  // Add the argument to the list to be allocated once we know the size of the
73  // block.
74  PendingMembers.push_back(
75  CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
76 
77  if (!ArgFlags.isInConsecutiveRegsLast())
78  return true;
79 
80  return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, 8);
81 }
82 
83 /// Given an [N x Ty] block, it should be passed in a consecutive sequence of
84 /// registers. If no such sequence is available, mark the rest of the registers
85 /// of that type as used and place the argument on the stack.
86 static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
87  CCValAssign::LocInfo &LocInfo,
88  ISD::ArgFlagsTy &ArgFlags, CCState &State) {
89  // Try to allocate a contiguous block of registers, each of the correct
90  // size to hold one member.
91  ArrayRef<uint16_t> RegList;
92  if (LocVT.SimpleTy == MVT::i64)
93  RegList = XRegList;
94  else if (LocVT.SimpleTy == MVT::f16)
95  RegList = HRegList;
96  else if (LocVT.SimpleTy == MVT::f32 || LocVT.is32BitVector())
97  RegList = SRegList;
98  else if (LocVT.SimpleTy == MVT::f64 || LocVT.is64BitVector())
99  RegList = DRegList;
100  else if (LocVT.SimpleTy == MVT::f128 || LocVT.is128BitVector())
101  RegList = QRegList;
102  else {
103  // Not an array we want to split up after all.
104  return false;
105  }
106 
107  SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
108 
109  // Add the argument to the list to be allocated once we know the size of the
110  // block.
111  PendingMembers.push_back(
112  CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
113 
114  if (!ArgFlags.isInConsecutiveRegsLast())
115  return true;
116 
117  unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
118  if (RegResult) {
119  for (auto &It : PendingMembers) {
120  It.convertToReg(RegResult);
121  State.addLoc(It);
122  ++RegResult;
123  }
124  PendingMembers.clear();
125  return true;
126  }
127 
128  // Mark all regs in the class as unavailable
129  for (auto Reg : RegList)
130  State.AllocateReg(Reg);
131 
132  const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>(
133  State.getMachineFunction().getSubtarget());
134  unsigned SlotAlign = Subtarget.isTargetDarwin() ? 1 : 8;
135 
136  return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign);
137 }
138 
139 }
140 
141 #endif
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
unsigned getStackAlignment() const
Definition: DataLayout.h:253
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: APInt.h:33
void addLoc(const CCValAssign &V)
Reg
All possible values of the reg field in the ModR/M byte.
SimpleValueType SimpleTy
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
SmallVectorImpl< llvm::CCValAssign > & getPendingLocs()
MachineFunction & getMachineFunction() const
static const uint16_t QRegList[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:31
bool isInConsecutiveRegsLast() const
unsigned AllocateRegBlock(ArrayRef< uint16_t > Regs, unsigned RegsRequired)
AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive registers.
MVT - Machine Value Type.
CCState - This class holds information needed while lowering arguments and return values...
const DataLayout * getDataLayout() const
Deprecated in 3.7, will be removed in 3.8.
static const uint16_t SRegList[]
bool is64BitVector() const
is64BitVector - Return true if this is a 64-bit vector type.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
bool is128BitVector() const
is128BitVector - Return true if this is a 128-bit vector type.
bool isTargetDarwin() const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
static const uint16_t 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.