/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/AArch64/AArch64CallingConvention.h
Line | Count | Source |
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" |
21 | | #include "llvm/CodeGen/CallingConvLower.h" |
22 | | #include "llvm/IR/CallingConv.h" |
23 | | #include "llvm/Target/TargetInstrInfo.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 | 84 | CCState &State, unsigned SlotAlign) { |
47 | 84 | unsigned Size = LocVT.getSizeInBits() / 8; |
48 | 84 | unsigned StackAlign = |
49 | 84 | State.getMachineFunction().getDataLayout().getStackAlignment(); |
50 | 84 | unsigned Align = std::min(ArgFlags.getOrigAlign(), StackAlign); |
51 | 84 | |
52 | 175 | for (auto &It : PendingMembers) { |
53 | 175 | It.convertToMem(State.AllocateStack(Size, std::max(Align, SlotAlign))); |
54 | 175 | State.addLoc(It); |
55 | 175 | SlotAlign = 1; |
56 | 175 | } |
57 | 84 | |
58 | 84 | // All pending members have now been allocated |
59 | 84 | PendingMembers.clear(); |
60 | 84 | return true; |
61 | 84 | } Unexecuted instantiation: AArch64FastISel.cpp:(anonymous namespace)::finishStackBlock(llvm::SmallVectorImpl<llvm::CCValAssign>&, llvm::MVT, llvm::ISD::ArgFlagsTy&, llvm::CCState&, unsigned int) AArch64ISelLowering.cpp:(anonymous namespace)::finishStackBlock(llvm::SmallVectorImpl<llvm::CCValAssign>&, llvm::MVT, llvm::ISD::ArgFlagsTy&, llvm::CCState&, unsigned int) Line | Count | Source | 46 | 84 | CCState &State, unsigned SlotAlign) { | 47 | 84 | unsigned Size = LocVT.getSizeInBits() / 8; | 48 | 84 | unsigned StackAlign = | 49 | 84 | State.getMachineFunction().getDataLayout().getStackAlignment(); | 50 | 84 | unsigned Align = std::min(ArgFlags.getOrigAlign(), StackAlign); | 51 | 84 | | 52 | 175 | for (auto &It : PendingMembers) { | 53 | 175 | It.convertToMem(State.AllocateStack(Size, std::max(Align, SlotAlign))); | 54 | 175 | State.addLoc(It); | 55 | 175 | SlotAlign = 1; | 56 | 175 | } | 57 | 84 | | 58 | 84 | // All pending members have now been allocated | 59 | 84 | PendingMembers.clear(); | 60 | 84 | return true; | 61 | 84 | } |
|
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 | 23 | ISD::ArgFlagsTy &ArgFlags, CCState &State) { |
68 | 23 | SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs(); |
69 | 23 | |
70 | 23 | // Add the argument to the list to be allocated once we know the size of the |
71 | 23 | // block. |
72 | 23 | PendingMembers.push_back( |
73 | 23 | CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); |
74 | 23 | |
75 | 23 | if (!ArgFlags.isInConsecutiveRegsLast()) |
76 | 12 | return true; |
77 | 23 | |
78 | 11 | return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, 8); |
79 | 23 | } Unexecuted instantiation: AArch64FastISel.cpp:(anonymous namespace)::CC_AArch64_Custom_Stack_Block(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&) AArch64ISelLowering.cpp:(anonymous namespace)::CC_AArch64_Custom_Stack_Block(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&) Line | Count | Source | 67 | 23 | ISD::ArgFlagsTy &ArgFlags, CCState &State) { | 68 | 23 | SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs(); | 69 | 23 | | 70 | 23 | // Add the argument to the list to be allocated once we know the size of the | 71 | 23 | // block. | 72 | 23 | PendingMembers.push_back( | 73 | 23 | CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); | 74 | 23 | | 75 | 23 | if (!ArgFlags.isInConsecutiveRegsLast()) | 76 | 12 | return true; | 77 | 23 | | 78 | 11 | return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, 8); | 79 | 23 | } |
|
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 | 2.25k | ISD::ArgFlagsTy &ArgFlags, CCState &State) { |
87 | 2.25k | // Try to allocate a contiguous block of registers, each of the correct |
88 | 2.25k | // size to hold one member. |
89 | 2.25k | ArrayRef<MCPhysReg> RegList; |
90 | 2.25k | if (LocVT.SimpleTy == MVT::i64) |
91 | 262 | RegList = XRegList; |
92 | 1.99k | else if (1.99k LocVT.SimpleTy == MVT::f161.99k ) |
93 | 4 | RegList = HRegList; |
94 | 1.98k | else if (1.98k LocVT.SimpleTy == MVT::f32 || 1.98k LocVT.is32BitVector()1.66k ) |
95 | 326 | RegList = SRegList; |
96 | 1.66k | else if (1.66k LocVT.SimpleTy == MVT::f64 || 1.66k LocVT.is64BitVector()600 ) |
97 | 1.08k | RegList = DRegList; |
98 | 572 | else if (572 LocVT.SimpleTy == MVT::f128 || 572 LocVT.is128BitVector()572 ) |
99 | 52 | RegList = QRegList; |
100 | 520 | else { |
101 | 520 | // Not an array we want to split up after all. |
102 | 520 | return false; |
103 | 520 | } |
104 | 2.25k | |
105 | 1.73k | SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs(); |
106 | 1.73k | |
107 | 1.73k | // Add the argument to the list to be allocated once we know the size of the |
108 | 1.73k | // block. |
109 | 1.73k | PendingMembers.push_back( |
110 | 1.73k | CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); |
111 | 1.73k | |
112 | 1.73k | if (!ArgFlags.isInConsecutiveRegsLast()) |
113 | 1.16k | return true; |
114 | 1.73k | |
115 | 567 | unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size()); |
116 | 567 | if (RegResult567 ) { |
117 | 1.58k | for (auto &It : PendingMembers) { |
118 | 1.58k | It.convertToReg(RegResult); |
119 | 1.58k | State.addLoc(It); |
120 | 1.58k | ++RegResult; |
121 | 1.58k | } |
122 | 494 | PendingMembers.clear(); |
123 | 494 | return true; |
124 | 494 | } |
125 | 567 | |
126 | 567 | // Mark all regs in the class as unavailable |
127 | 73 | for (auto Reg : RegList) |
128 | 584 | State.AllocateReg(Reg); |
129 | 73 | |
130 | 73 | const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>( |
131 | 73 | State.getMachineFunction().getSubtarget()); |
132 | 73 | unsigned SlotAlign = Subtarget.isTargetDarwin() ? 144 : 829 ; |
133 | 73 | |
134 | 73 | return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign); |
135 | 2.25k | } Unexecuted instantiation: AArch64FastISel.cpp:(anonymous namespace)::CC_AArch64_Custom_Block(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&) AArch64ISelLowering.cpp:(anonymous namespace)::CC_AArch64_Custom_Block(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&) Line | Count | Source | 86 | 2.25k | ISD::ArgFlagsTy &ArgFlags, CCState &State) { | 87 | 2.25k | // Try to allocate a contiguous block of registers, each of the correct | 88 | 2.25k | // size to hold one member. | 89 | 2.25k | ArrayRef<MCPhysReg> RegList; | 90 | 2.25k | if (LocVT.SimpleTy == MVT::i64) | 91 | 262 | RegList = XRegList; | 92 | 1.99k | else if (1.99k LocVT.SimpleTy == MVT::f161.99k ) | 93 | 4 | RegList = HRegList; | 94 | 1.98k | else if (1.98k LocVT.SimpleTy == MVT::f32 || 1.98k LocVT.is32BitVector()1.66k ) | 95 | 326 | RegList = SRegList; | 96 | 1.66k | else if (1.66k LocVT.SimpleTy == MVT::f64 || 1.66k LocVT.is64BitVector()600 ) | 97 | 1.08k | RegList = DRegList; | 98 | 572 | else if (572 LocVT.SimpleTy == MVT::f128 || 572 LocVT.is128BitVector()572 ) | 99 | 52 | RegList = QRegList; | 100 | 520 | else { | 101 | 520 | // Not an array we want to split up after all. | 102 | 520 | return false; | 103 | 520 | } | 104 | 2.25k | | 105 | 1.73k | SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs(); | 106 | 1.73k | | 107 | 1.73k | // Add the argument to the list to be allocated once we know the size of the | 108 | 1.73k | // block. | 109 | 1.73k | PendingMembers.push_back( | 110 | 1.73k | CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); | 111 | 1.73k | | 112 | 1.73k | if (!ArgFlags.isInConsecutiveRegsLast()) | 113 | 1.16k | return true; | 114 | 1.73k | | 115 | 567 | unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size()); | 116 | 567 | if (RegResult567 ) { | 117 | 1.58k | for (auto &It : PendingMembers) { | 118 | 1.58k | It.convertToReg(RegResult); | 119 | 1.58k | State.addLoc(It); | 120 | 1.58k | ++RegResult; | 121 | 1.58k | } | 122 | 494 | PendingMembers.clear(); | 123 | 494 | return true; | 124 | 494 | } | 125 | 567 | | 126 | 567 | // Mark all regs in the class as unavailable | 127 | 73 | for (auto Reg : RegList) | 128 | 584 | State.AllocateReg(Reg); | 129 | 73 | | 130 | 73 | const AArch64Subtarget &Subtarget = static_cast<const AArch64Subtarget &>( | 131 | 73 | State.getMachineFunction().getSubtarget()); | 132 | 73 | unsigned SlotAlign = Subtarget.isTargetDarwin() ? 144 : 829 ; | 133 | 73 | | 134 | 73 | return finishStackBlock(PendingMembers, LocVT, ArgFlags, State, SlotAlign); | 135 | 2.25k | } |
|
136 | | |
137 | | } |
138 | | |
139 | | #endif |