Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/X86/X86CallingConv.cpp
Line
Count
Source (jump to first uncovered line)
1
//=== X86CallingConv.cpp - X86 Custom Calling Convention Impl   -*- 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 implementation of custom routines for the X86
11
// Calling Convention that aren't done by tablegen.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "MCTargetDesc/X86MCTargetDesc.h"
16
#include "X86Subtarget.h"
17
#include "llvm/CodeGen/CallingConvLower.h"
18
#include "llvm/IR/CallingConv.h"
19
20
namespace llvm {
21
22
bool CC_X86_32_RegCall_Assign2Regs(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
23
                                   CCValAssign::LocInfo &LocInfo,
24
30
                                   ISD::ArgFlagsTy &ArgFlags, CCState &State) {
25
30
  // List of GPR registers that are available to store values in regcall
26
30
  // calling convention.
27
30
  static const MCPhysReg RegList[] = {X86::EAX, X86::ECX, X86::EDX, X86::EDI,
28
30
                                      X86::ESI};
29
30
30
30
  // The vector will save all the available registers for allocation.
31
30
  SmallVector<unsigned, 5> AvailableRegs;
32
30
33
30
  // searching for the available registers.
34
150
  for (auto Reg : RegList) {
35
150
    if (!State.isAllocated(Reg))
36
58
      AvailableRegs.push_back(Reg);
37
150
  }
38
30
39
30
  const size_t RequiredGprsUponSplit = 2;
40
30
  if (AvailableRegs.size() < RequiredGprsUponSplit)
41
22
    return false; // Not enough free registers - continue the search.
42
8
43
8
  // Allocating the available registers.
44
24
  
for (unsigned I = 0; 8
I < RequiredGprsUponSplit24
;
I++16
) {
45
16
46
16
    // Marking the register as located.
47
16
    unsigned Reg = State.AllocateReg(AvailableRegs[I]);
48
16
49
16
    // Since we previously made sure that 2 registers are available
50
16
    // we expect that a real register number will be returned.
51
16
    assert(Reg && "Expecting a register will be available");
52
16
53
16
    // Assign the value to the allocated register
54
16
    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
55
16
  }
56
30
57
30
  // Successful in allocating regsiters - stop scanning next rules.
58
30
  return true;
59
30
}
60
61
153
static ArrayRef<MCPhysReg> CC_X86_VectorCallGetSSEs(const MVT &ValVT) {
62
153
  if (
ValVT.is512BitVector()153
) {
63
7
    static const MCPhysReg RegListZMM[] = {X86::ZMM0, X86::ZMM1, X86::ZMM2,
64
7
                                           X86::ZMM3, X86::ZMM4, X86::ZMM5};
65
7
    return makeArrayRef(std::begin(RegListZMM), std::end(RegListZMM));
66
7
  }
67
146
68
146
  
if (146
ValVT.is256BitVector()146
) {
69
7
    static const MCPhysReg RegListYMM[] = {X86::YMM0, X86::YMM1, X86::YMM2,
70
7
                                           X86::YMM3, X86::YMM4, X86::YMM5};
71
7
    return makeArrayRef(std::begin(RegListYMM), std::end(RegListYMM));
72
7
  }
73
139
74
139
  static const MCPhysReg RegListXMM[] = {X86::XMM0, X86::XMM1, X86::XMM2,
75
139
                                         X86::XMM3, X86::XMM4, X86::XMM5};
76
139
  return makeArrayRef(std::begin(RegListXMM), std::end(RegListXMM));
77
139
}
78
79
40
static ArrayRef<MCPhysReg> CC_X86_64_VectorCallGetGPRs() {
80
40
  static const MCPhysReg RegListGPR[] = {X86::RCX, X86::RDX, X86::R8, X86::R9};
81
40
  return makeArrayRef(std::begin(RegListGPR), std::end(RegListGPR));
82
40
}
83
84
static bool CC_X86_VectorCallAssignRegister(unsigned &ValNo, MVT &ValVT,
85
                                            MVT &LocVT,
86
                                            CCValAssign::LocInfo &LocInfo,
87
                                            ISD::ArgFlagsTy &ArgFlags,
88
58
                                            CCState &State) {
89
58
90
58
  ArrayRef<MCPhysReg> RegList = CC_X86_VectorCallGetSSEs(ValVT);
91
58
  bool Is64bit = static_cast<const X86Subtarget &>(
92
58
                     State.getMachineFunction().getSubtarget())
93
58
                     .is64Bit();
94
58
95
177
  for (auto Reg : RegList) {
96
177
    // If the register is not marked as allocated - assign to it.
97
177
    if (
!State.isAllocated(Reg)177
) {
98
44
      unsigned AssigedReg = State.AllocateReg(Reg);
99
44
      assert(AssigedReg == Reg && "Expecting a valid register allocation");
100
44
      State.addLoc(
101
44
          CCValAssign::getReg(ValNo, ValVT, AssigedReg, LocVT, LocInfo));
102
44
      return true;
103
44
    }
104
133
    // If the register is marked as shadow allocated - assign to it.
105
133
    
if (133
Is64bit && 133
State.IsShadowAllocatedReg(Reg)70
) {
106
14
      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
107
14
      return true;
108
14
    }
109
0
  }
110
0
111
0
  
llvm_unreachable0
("Clang should ensure that hva marked vectors will have "
112
0
                   "an available register.");
113
0
  return false;
114
58
}
115
116
bool CC_X86_64_VectorCall(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
117
                          CCValAssign::LocInfo &LocInfo,
118
152
                          ISD::ArgFlagsTy &ArgFlags, CCState &State) {
119
152
  // On the second pass, go through the HVAs only.
120
152
  if (
ArgFlags.isSecArgPass()152
) {
121
76
    if (ArgFlags.isHva())
122
29
      return CC_X86_VectorCallAssignRegister(ValNo, ValVT, LocVT, LocInfo,
123
29
                                             ArgFlags, State);
124
47
    return true;
125
47
  }
126
76
127
76
  // Process only vector types as defined by vectorcall spec:
128
76
  // "A vector type is either a floating-point type, for example,
129
76
  //  a float or double, or an SIMD vector type, for example, __m128 or __m256".
130
76
  
if (76
!(ValVT.isFloatingPoint() ||
131
76
        
(ValVT.isVector() && 23
ValVT.getSizeInBits() >= 1288
))) {
132
15
    // If R9 was already assigned it means that we are after the fourth element
133
15
    // and because this is not an HVA / Vector type, we need to allocate
134
15
    // shadow XMM register.
135
15
    if (
State.isAllocated(X86::R9)15
) {
136
2
      // Assign shadow XMM register.
137
2
      (void)State.AllocateReg(CC_X86_VectorCallGetSSEs(ValVT));
138
2
    }
139
15
140
15
    return false;
141
15
  }
142
61
143
61
  
if (61
!ArgFlags.isHva() || 61
ArgFlags.isHvaStart()29
) {
144
40
    // Assign shadow GPR register.
145
40
    (void)State.AllocateReg(CC_X86_64_VectorCallGetGPRs());
146
40
147
40
    // Assign XMM register - (shadow for HVA and non-shadow for non HVA).
148
40
    if (unsigned 
Reg40
= State.AllocateReg(CC_X86_VectorCallGetSSEs(ValVT))) {
149
38
      // In Vectorcall Calling convention, additional shadow stack can be
150
38
      // created on top of the basic 32 bytes of win64.
151
38
      // It can happen if the fifth or sixth argument is vector type or HVA.
152
38
      // At that case for each argument a shadow stack of 8 bytes is allocated.
153
38
      if (
Reg == X86::XMM4 || 38
Reg == X86::XMM535
)
154
6
        State.AllocateStack(8, 8);
155
38
156
38
      if (
!ArgFlags.isHva()38
) {
157
30
        State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
158
30
        return true; // Allocated a register - Stop the search.
159
30
      }
160
31
    }
161
40
  }
162
31
163
31
  // If this is an HVA - Stop the search,
164
31
  // otherwise continue the search.
165
31
  return ArgFlags.isHva();
166
31
}
167
168
bool CC_X86_32_VectorCall(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
169
                          CCValAssign::LocInfo &LocInfo,
170
240
                          ISD::ArgFlagsTy &ArgFlags, CCState &State) {
171
240
  // On the second pass, go through the HVAs only.
172
240
  if (
ArgFlags.isSecArgPass()240
) {
173
105
    if (ArgFlags.isHva())
174
29
      return CC_X86_VectorCallAssignRegister(ValNo, ValVT, LocVT, LocInfo,
175
29
                                             ArgFlags, State);
176
76
    return true;
177
76
  }
178
135
179
135
  // Process only vector types as defined by vectorcall spec:
180
135
  // "A vector type is either a floating point type, for example,
181
135
  //  a float or double, or an SIMD vector type, for example, __m128 or __m256".
182
135
  
if (135
!(ValVT.isFloatingPoint() ||
183
135
        
(ValVT.isVector() && 61
ValVT.getSizeInBits() >= 1288
))) {
184
53
    return false;
185
53
  }
186
82
187
82
  
if (82
ArgFlags.isHva()82
)
188
29
    return true; // If this is an HVA - Stop the search.
189
53
190
53
  // Assign XMM register.
191
53
  
if (unsigned 53
Reg53
= State.AllocateReg(CC_X86_VectorCallGetSSEs(ValVT))) {
192
48
    State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
193
48
    return true;
194
48
  }
195
5
196
5
  // In case we did not find an available XMM register for a vector -
197
5
  // pass it indirectly.
198
5
  // It is similar to CCPassIndirect, with the addition of inreg.
199
5
  
if (5
!ValVT.isFloatingPoint()5
) {
200
1
    LocVT = MVT::i32;
201
1
    LocInfo = CCValAssign::Indirect;
202
1
    ArgFlags.setInReg();
203
1
  }
204
240
205
240
  return false; // No register was assigned - Continue the search.
206
240
}
207
208
} // End llvm namespace