Coverage Report

Created: 2019-01-28 19:20

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/ARMCallingConv.h
Line
Count
Source (jump to first uncovered line)
1
//=== ARMCallingConv.h - ARM Custom Calling Convention Routines -*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file contains the custom routines for the ARM Calling Convention that
10
// aren't done by tablegen.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_LIB_TARGET_ARM_ARMCALLINGCONV_H
15
#define LLVM_LIB_TARGET_ARM_ARMCALLINGCONV_H
16
17
#include "ARM.h"
18
#include "ARMBaseInstrInfo.h"
19
#include "ARMSubtarget.h"
20
#include "llvm/CodeGen/CallingConvLower.h"
21
#include "llvm/CodeGen/TargetInstrInfo.h"
22
#include "llvm/IR/CallingConv.h"
23
24
namespace llvm {
25
26
// APCS f64 is in register pairs, possibly split to stack
27
static bool f64AssignAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
28
                          CCValAssign::LocInfo &LocInfo,
29
1.15k
                          CCState &State, bool CanFail) {
30
1.15k
  static const MCPhysReg RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
31
1.15k
32
1.15k
  // Try to get the first register.
33
1.15k
  if (unsigned Reg = State.AllocateReg(RegList))
34
650
    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
35
503
  else {
36
503
    // For the 2nd half of a v2f64, do not fail.
37
503
    if (CanFail)
38
498
      return false;
39
5
40
5
    // Put the whole thing on the stack.
41
5
    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
42
5
                                           State.AllocateStack(8, 4),
43
5
                                           LocVT, LocInfo));
44
5
    return true;
45
5
  }
46
650
47
650
  // Try to get the second register.
48
650
  if (unsigned Reg = State.AllocateReg(RegList))
49
610
    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
50
40
  else
51
40
    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
52
40
                                           State.AllocateStack(4, 4),
53
40
                                           LocVT, LocInfo));
54
650
  return true;
55
650
}
ARMFastISel.cpp:llvm::f64AssignAPCS(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::CCState&, bool)
Line
Count
Source
29
424
                          CCState &State, bool CanFail) {
30
424
  static const MCPhysReg RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
31
424
32
424
  // Try to get the first register.
33
424
  if (unsigned Reg = State.AllocateReg(RegList))
34
5
    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
35
419
  else {
36
419
    // For the 2nd half of a v2f64, do not fail.
37
419
    if (CanFail)
38
419
      return false;
39
0
40
0
    // Put the whole thing on the stack.
41
0
    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
42
0
                                           State.AllocateStack(8, 4),
43
0
                                           LocVT, LocInfo));
44
0
    return true;
45
0
  }
46
5
47
5
  // Try to get the second register.
48
5
  if (unsigned Reg = State.AllocateReg(RegList))
49
4
    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
50
1
  else
51
1
    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
52
1
                                           State.AllocateStack(4, 4),
53
1
                                           LocVT, LocInfo));
54
5
  return true;
55
5
}
ARMISelLowering.cpp:llvm::f64AssignAPCS(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::CCState&, bool)
Line
Count
Source
29
729
                          CCState &State, bool CanFail) {
30
729
  static const MCPhysReg RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
31
729
32
729
  // Try to get the first register.
33
729
  if (unsigned Reg = State.AllocateReg(RegList))
34
645
    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
35
84
  else {
36
84
    // For the 2nd half of a v2f64, do not fail.
37
84
    if (CanFail)
38
79
      return false;
39
5
40
5
    // Put the whole thing on the stack.
41
5
    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
42
5
                                           State.AllocateStack(8, 4),
43
5
                                           LocVT, LocInfo));
44
5
    return true;
45
5
  }
46
645
47
645
  // Try to get the second register.
48
645
  if (unsigned Reg = State.AllocateReg(RegList))
49
606
    State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
50
39
  else
51
39
    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
52
39
                                           State.AllocateStack(4, 4),
53
39
                                           LocVT, LocInfo));
54
645
  return true;
55
645
}
56
57
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
58
                                   CCValAssign::LocInfo &LocInfo,
59
                                   ISD::ArgFlagsTy &ArgFlags,
60
1.06k
                                   CCState &State) {
61
1.06k
  if (!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
62
498
    return false;
63
571
  if (LocVT == MVT::v2f64 &&
64
571
      
!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, false)84
)
65
0
    return false;
66
571
  return true;  // we handled it
67
571
}
ARMFastISel.cpp:llvm::CC_ARM_APCS_Custom_f64(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
Line
Count
Source
60
422
                                   CCState &State) {
61
422
  if (!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
62
419
    return false;
63
3
  if (LocVT == MVT::v2f64 &&
64
3
      
!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, false)2
)
65
0
    return false;
66
3
  return true;  // we handled it
67
3
}
ARMISelLowering.cpp:llvm::CC_ARM_APCS_Custom_f64(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
Line
Count
Source
60
647
                                   CCState &State) {
61
647
  if (!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
62
79
    return false;
63
568
  if (LocVT == MVT::v2f64 &&
64
568
      
!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, false)82
)
65
0
    return false;
66
568
  return true;  // we handled it
67
568
}
68
69
// AAPCS f64 is in aligned register pairs
70
static bool f64AssignAAPCS(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
71
                           CCValAssign::LocInfo &LocInfo,
72
1.94k
                           CCState &State, bool CanFail) {
73
1.94k
  static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
74
1.94k
  static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
75
1.94k
  static const MCPhysReg ShadowRegList[] = { ARM::R0, ARM::R1 };
76
1.94k
  static const MCPhysReg GPRArgRegs[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
77
1.94k
78
1.94k
  unsigned Reg = State.AllocateReg(HiRegList, ShadowRegList);
79
1.94k
  if (Reg == 0) {
80
428
81
428
    // If we had R3 unallocated only, now we still must to waste it.
82
428
    Reg = State.AllocateReg(GPRArgRegs);
83
428
    assert((!Reg || Reg == ARM::R3) && "Wrong GPRs usage for f64");
84
428
85
428
    // For the 2nd half of a v2f64, do not just fail.
86
428
    if (CanFail)
87
413
      return false;
88
15
89
15
    // Put the whole thing on the stack.
90
15
    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
91
15
                                           State.AllocateStack(8, 8),
92
15
                                           LocVT, LocInfo));
93
15
    return true;
94
15
  }
95
1.51k
96
1.51k
  unsigned i;
97
2.15k
  for (i = 0; i < 2; 
++i638
)
98
2.15k
    if (HiRegList[i] == Reg)
99
1.51k
      break;
100
1.51k
101
1.51k
  unsigned T = State.AllocateReg(LoRegList[i]);
102
1.51k
  (void)T;
103
1.51k
  assert(T == LoRegList[i] && "Could not allocate register");
104
1.51k
105
1.51k
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
106
1.51k
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
107
1.51k
                                         LocVT, LocInfo));
108
1.51k
  return true;
109
1.51k
}
ARMFastISel.cpp:llvm::f64AssignAAPCS(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::CCState&, bool)
Line
Count
Source
72
4
                           CCState &State, bool CanFail) {
73
4
  static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
74
4
  static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
75
4
  static const MCPhysReg ShadowRegList[] = { ARM::R0, ARM::R1 };
76
4
  static const MCPhysReg GPRArgRegs[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
77
4
78
4
  unsigned Reg = State.AllocateReg(HiRegList, ShadowRegList);
79
4
  if (Reg == 0) {
80
0
81
0
    // If we had R3 unallocated only, now we still must to waste it.
82
0
    Reg = State.AllocateReg(GPRArgRegs);
83
0
    assert((!Reg || Reg == ARM::R3) && "Wrong GPRs usage for f64");
84
0
85
0
    // For the 2nd half of a v2f64, do not just fail.
86
0
    if (CanFail)
87
0
      return false;
88
0
89
0
    // Put the whole thing on the stack.
90
0
    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
91
0
                                           State.AllocateStack(8, 8),
92
0
                                           LocVT, LocInfo));
93
0
    return true;
94
0
  }
95
4
96
4
  unsigned i;
97
6
  for (i = 0; i < 2; 
++i2
)
98
6
    if (HiRegList[i] == Reg)
99
4
      break;
100
4
101
4
  unsigned T = State.AllocateReg(LoRegList[i]);
102
4
  (void)T;
103
4
  assert(T == LoRegList[i] && "Could not allocate register");
104
4
105
4
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
106
4
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
107
4
                                         LocVT, LocInfo));
108
4
  return true;
109
4
}
ARMISelLowering.cpp:llvm::f64AssignAAPCS(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::CCState&, bool)
Line
Count
Source
72
1.94k
                           CCState &State, bool CanFail) {
73
1.94k
  static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
74
1.94k
  static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
75
1.94k
  static const MCPhysReg ShadowRegList[] = { ARM::R0, ARM::R1 };
76
1.94k
  static const MCPhysReg GPRArgRegs[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
77
1.94k
78
1.94k
  unsigned Reg = State.AllocateReg(HiRegList, ShadowRegList);
79
1.94k
  if (Reg == 0) {
80
428
81
428
    // If we had R3 unallocated only, now we still must to waste it.
82
428
    Reg = State.AllocateReg(GPRArgRegs);
83
428
    assert((!Reg || Reg == ARM::R3) && "Wrong GPRs usage for f64");
84
428
85
428
    // For the 2nd half of a v2f64, do not just fail.
86
428
    if (CanFail)
87
413
      return false;
88
15
89
15
    // Put the whole thing on the stack.
90
15
    State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
91
15
                                           State.AllocateStack(8, 8),
92
15
                                           LocVT, LocInfo));
93
15
    return true;
94
15
  }
95
1.51k
96
1.51k
  unsigned i;
97
2.14k
  for (i = 0; i < 2; 
++i636
)
98
2.14k
    if (HiRegList[i] == Reg)
99
1.51k
      break;
100
1.51k
101
1.51k
  unsigned T = State.AllocateReg(LoRegList[i]);
102
1.51k
  (void)T;
103
1.51k
  assert(T == LoRegList[i] && "Could not allocate register");
104
1.51k
105
1.51k
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
106
1.51k
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
107
1.51k
                                         LocVT, LocInfo));
108
1.51k
  return true;
109
1.51k
}
110
111
static bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
112
                                    CCValAssign::LocInfo &LocInfo,
113
                                    ISD::ArgFlagsTy &ArgFlags,
114
1.76k
                                    CCState &State) {
115
1.76k
  if (!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
116
413
    return false;
117
1.34k
  if (LocVT == MVT::v2f64 &&
118
1.34k
      
!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, false)184
)
119
0
    return false;
120
1.34k
  return true;  // we handled it
121
1.34k
}
ARMFastISel.cpp:llvm::CC_ARM_AAPCS_Custom_f64(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
Line
Count
Source
114
2
                                    CCState &State) {
115
2
  if (!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
116
0
    return false;
117
2
  if (LocVT == MVT::v2f64 &&
118
2
      !f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, false))
119
0
    return false;
120
2
  return true;  // we handled it
121
2
}
ARMISelLowering.cpp:llvm::CC_ARM_AAPCS_Custom_f64(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
Line
Count
Source
114
1.75k
                                    CCState &State) {
115
1.75k
  if (!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
116
413
    return false;
117
1.34k
  if (LocVT == MVT::v2f64 &&
118
1.34k
      
!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, false)182
)
119
0
    return false;
120
1.34k
  return true;  // we handled it
121
1.34k
}
122
123
static bool f64RetAssign(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
124
6.36k
                         CCValAssign::LocInfo &LocInfo, CCState &State) {
125
6.36k
  static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
126
6.36k
  static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
127
6.36k
128
6.36k
  unsigned Reg = State.AllocateReg(HiRegList, LoRegList);
129
6.36k
  if (Reg == 0)
130
61
    return false; // we didn't handle it
131
6.30k
132
6.30k
  unsigned i;
133
8.06k
  for (i = 0; i < 2; 
++i1.76k
)
134
8.06k
    if (HiRegList[i] == Reg)
135
6.30k
      break;
136
6.30k
137
6.30k
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
138
6.30k
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
139
6.30k
                                         LocVT, LocInfo));
140
6.30k
  return true;
141
6.30k
}
ARMFastISel.cpp:llvm::f64RetAssign(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::CCState&)
Line
Count
Source
124
14
                         CCValAssign::LocInfo &LocInfo, CCState &State) {
125
14
  static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
126
14
  static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
127
14
128
14
  unsigned Reg = State.AllocateReg(HiRegList, LoRegList);
129
14
  if (Reg == 0)
130
0
    return false; // we didn't handle it
131
14
132
14
  unsigned i;
133
21
  for (i = 0; i < 2; 
++i7
)
134
21
    if (HiRegList[i] == Reg)
135
14
      break;
136
14
137
14
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
138
14
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
139
14
                                         LocVT, LocInfo));
140
14
  return true;
141
14
}
ARMISelLowering.cpp:llvm::f64RetAssign(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::CCState&)
Line
Count
Source
124
6.34k
                         CCValAssign::LocInfo &LocInfo, CCState &State) {
125
6.34k
  static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
126
6.34k
  static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
127
6.34k
128
6.34k
  unsigned Reg = State.AllocateReg(HiRegList, LoRegList);
129
6.34k
  if (Reg == 0)
130
61
    return false; // we didn't handle it
131
6.28k
132
6.28k
  unsigned i;
133
8.04k
  for (i = 0; i < 2; 
++i1.75k
)
134
8.04k
    if (HiRegList[i] == Reg)
135
6.28k
      break;
136
6.28k
137
6.28k
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
138
6.28k
  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
139
6.28k
                                         LocVT, LocInfo));
140
6.28k
  return true;
141
6.28k
}
142
143
static bool RetCC_ARM_APCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
144
                                      CCValAssign::LocInfo &LocInfo,
145
                                      ISD::ArgFlagsTy &ArgFlags,
146
4.64k
                                      CCState &State) {
147
4.64k
  if (!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
148
61
    return false;
149
4.58k
  if (LocVT == MVT::v2f64 && 
!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State)1.72k
)
150
0
    return false;
151
4.58k
  return true;  // we handled it
152
4.58k
}
ARMFastISel.cpp:llvm::RetCC_ARM_APCS_Custom_f64(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
Line
Count
Source
146
7
                                      CCState &State) {
147
7
  if (!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
148
0
    return false;
149
7
  if (LocVT == MVT::v2f64 && !f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
150
0
    return false;
151
7
  return true;  // we handled it
152
7
}
ARMISelLowering.cpp:llvm::RetCC_ARM_APCS_Custom_f64(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
Line
Count
Source
146
4.63k
                                      CCState &State) {
147
4.63k
  if (!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
148
61
    return false;
149
4.57k
  if (LocVT == MVT::v2f64 && 
!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State)1.71k
)
150
0
    return false;
151
4.57k
  return true;  // we handled it
152
4.57k
}
153
154
static bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
155
                                       CCValAssign::LocInfo &LocInfo,
156
                                       ISD::ArgFlagsTy &ArgFlags,
157
3.98k
                                       CCState &State) {
158
3.98k
  return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
159
3.98k
                                   State);
160
3.98k
}
ARMFastISel.cpp:llvm::RetCC_ARM_AAPCS_Custom_f64(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
Line
Count
Source
157
2
                                       CCState &State) {
158
2
  return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
159
2
                                   State);
160
2
}
ARMISelLowering.cpp:llvm::RetCC_ARM_AAPCS_Custom_f64(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
Line
Count
Source
157
3.97k
                                       CCState &State) {
158
3.97k
  return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
159
3.97k
                                   State);
160
3.97k
}
161
162
static const MCPhysReg RRegList[] = { ARM::R0,  ARM::R1,  ARM::R2,  ARM::R3 };
163
164
static const MCPhysReg SRegList[] = { ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
165
                                      ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
166
                                      ARM::S8,  ARM::S9,  ARM::S10, ARM::S11,
167
                                      ARM::S12, ARM::S13, ARM::S14,  ARM::S15 };
168
static const MCPhysReg DRegList[] = { ARM::D0, ARM::D1, ARM::D2, ARM::D3,
169
                                      ARM::D4, ARM::D5, ARM::D6, ARM::D7 };
170
static const MCPhysReg QRegList[] = { ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3 };
171
172
173
// Allocate part of an AAPCS HFA or HVA. We assume that each member of the HA
174
// has InConsecutiveRegs set, and that the last member also has
175
// InConsecutiveRegsLast set. We must process all members of the HA before
176
// we can allocate it, as we need to know the total number of registers that
177
// will be needed in order to (attempt to) allocate a contiguous block.
178
static bool CC_ARM_AAPCS_Custom_Aggregate(unsigned &ValNo, MVT &ValVT,
179
                                          MVT &LocVT,
180
                                          CCValAssign::LocInfo &LocInfo,
181
                                          ISD::ArgFlagsTy &ArgFlags,
182
5.08k
                                          CCState &State) {
183
5.08k
  SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
184
5.08k
185
5.08k
  // AAPCS HFAs must have 1-4 elements, all of the same type
186
5.08k
  if (PendingMembers.size() > 0)
187
5.08k
    assert(PendingMembers[0].getLocVT() == LocVT);
188
5.08k
189
5.08k
  // Add the argument to the list to be allocated once we know the size of the
190
5.08k
  // aggregate. Store the type's required alignmnent as extra info for later: in
191
5.08k
  // the [N x i64] case all trace has been removed by the time we actually get
192
5.08k
  // to do allocation.
193
5.08k
  PendingMembers.push_back(CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo,
194
5.08k
                                                   ArgFlags.getOrigAlign()));
195
5.08k
196
5.08k
  if (!ArgFlags.isInConsecutiveRegsLast())
197
478
    return true;
198
4.61k
199
4.61k
  // Try to allocate a contiguous block of registers, each of the correct
200
4.61k
  // size to hold one member.
201
4.61k
  auto &DL = State.getMachineFunction().getDataLayout();
202
4.61k
  unsigned StackAlign = DL.getStackAlignment();
203
4.61k
  unsigned Align = std::min(PendingMembers[0].getExtraInfo(), StackAlign);
204
4.61k
205
4.61k
  ArrayRef<MCPhysReg> RegList;
206
4.61k
  switch (LocVT.SimpleTy) {
207
4.61k
  case MVT::i32: {
208
183
    RegList = RRegList;
209
183
    unsigned RegIdx = State.getFirstUnallocated(RegList);
210
183
211
183
    // First consume all registers that would give an unaligned object. Whether
212
183
    // we go on stack or in regs, no-one will be using them in future.
213
183
    unsigned RegAlign = alignTo(Align, 4) / 4;
214
188
    while (RegIdx % RegAlign != 0 && 
RegIdx < RegList.size()5
)
215
5
      State.AllocateReg(RegList[RegIdx++]);
216
183
217
183
    break;
218
4.61k
  }
219
4.61k
  case MVT::f16:
220
1.74k
  case MVT::f32:
221
1.74k
    RegList = SRegList;
222
1.74k
    break;
223
2.37k
  case MVT::v4f16:
224
2.37k
  case MVT::f64:
225
2.37k
    RegList = DRegList;
226
2.37k
    break;
227
2.37k
  case MVT::v8f16:
228
301
  case MVT::v2f64:
229
301
    RegList = QRegList;
230
301
    break;
231
301
  default:
232
0
    llvm_unreachable("Unexpected member type for block aggregate");
233
301
    
break0
;
234
4.61k
  }
235
4.61k
236
4.61k
  unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
237
4.61k
  if (RegResult) {
238
4.44k
    for (SmallVectorImpl<CCValAssign>::iterator It = PendingMembers.begin();
239
9.15k
         It != PendingMembers.end(); 
++It4.71k
) {
240
4.71k
      It->convertToReg(RegResult);
241
4.71k
      State.addLoc(*It);
242
4.71k
      ++RegResult;
243
4.71k
    }
244
4.44k
    PendingMembers.clear();
245
4.44k
    return true;
246
4.44k
  }
247
163
248
163
  // Register allocation failed, we'll be needing the stack
249
163
  unsigned Size = LocVT.getSizeInBits() / 8;
250
163
  if (LocVT == MVT::i32 && 
State.getNextStackOffset() == 092
) {
251
79
    // If nothing else has used the stack until this point, a non-HFA aggregate
252
79
    // can be split between regs and stack.
253
79
    unsigned RegIdx = State.getFirstUnallocated(RegList);
254
242
    for (auto &It : PendingMembers) {
255
242
      if (RegIdx >= RegList.size())
256
125
        It.convertToMem(State.AllocateStack(Size, Size));
257
117
      else
258
117
        It.convertToReg(State.AllocateReg(RegList[RegIdx++]));
259
242
260
242
      State.addLoc(It);
261
242
    }
262
79
    PendingMembers.clear();
263
79
    return true;
264
84
  } else if (LocVT != MVT::i32)
265
71
    RegList = SRegList;
266
163
267
163
  // Mark all regs as unavailable (AAPCS rule C.2.vfp for VFP, C.6 for core)
268
163
  
for (auto Reg : RegList)84
269
1.18k
    State.AllocateReg(Reg);
270
84
271
84
  // After the first item has been allocated, the rest are packed as tightly as
272
84
  // possible. (E.g. an incoming i64 would have starting Align of 8, but we'll
273
84
  // be allocating a bunch of i32 slots).
274
84
  unsigned RestAlign = std::min(Align, Size);
275
84
276
134
  for (auto &It : PendingMembers) {
277
134
    It.convertToMem(State.AllocateStack(Size, Align));
278
134
    State.addLoc(It);
279
134
    Align = RestAlign;
280
134
  }
281
84
282
84
  // All pending members have now been allocated
283
84
  PendingMembers.clear();
284
84
285
84
  // This will be allocated by the last member of the aggregate
286
84
  return true;
287
163
}
Unexecuted instantiation: ARMFastISel.cpp:llvm::CC_ARM_AAPCS_Custom_Aggregate(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
ARMISelLowering.cpp:llvm::CC_ARM_AAPCS_Custom_Aggregate(unsigned int&, llvm::MVT&, llvm::MVT&, llvm::CCValAssign::LocInfo&, llvm::ISD::ArgFlagsTy&, llvm::CCState&)
Line
Count
Source
182
5.08k
                                          CCState &State) {
183
5.08k
  SmallVectorImpl<CCValAssign> &PendingMembers = State.getPendingLocs();
184
5.08k
185
5.08k
  // AAPCS HFAs must have 1-4 elements, all of the same type
186
5.08k
  if (PendingMembers.size() > 0)
187
5.08k
    assert(PendingMembers[0].getLocVT() == LocVT);
188
5.08k
189
5.08k
  // Add the argument to the list to be allocated once we know the size of the
190
5.08k
  // aggregate. Store the type's required alignmnent as extra info for later: in
191
5.08k
  // the [N x i64] case all trace has been removed by the time we actually get
192
5.08k
  // to do allocation.
193
5.08k
  PendingMembers.push_back(CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo,
194
5.08k
                                                   ArgFlags.getOrigAlign()));
195
5.08k
196
5.08k
  if (!ArgFlags.isInConsecutiveRegsLast())
197
478
    return true;
198
4.61k
199
4.61k
  // Try to allocate a contiguous block of registers, each of the correct
200
4.61k
  // size to hold one member.
201
4.61k
  auto &DL = State.getMachineFunction().getDataLayout();
202
4.61k
  unsigned StackAlign = DL.getStackAlignment();
203
4.61k
  unsigned Align = std::min(PendingMembers[0].getExtraInfo(), StackAlign);
204
4.61k
205
4.61k
  ArrayRef<MCPhysReg> RegList;
206
4.61k
  switch (LocVT.SimpleTy) {
207
4.61k
  case MVT::i32: {
208
183
    RegList = RRegList;
209
183
    unsigned RegIdx = State.getFirstUnallocated(RegList);
210
183
211
183
    // First consume all registers that would give an unaligned object. Whether
212
183
    // we go on stack or in regs, no-one will be using them in future.
213
183
    unsigned RegAlign = alignTo(Align, 4) / 4;
214
188
    while (RegIdx % RegAlign != 0 && 
RegIdx < RegList.size()5
)
215
5
      State.AllocateReg(RegList[RegIdx++]);
216
183
217
183
    break;
218
4.61k
  }
219
4.61k
  case MVT::f16:
220
1.74k
  case MVT::f32:
221
1.74k
    RegList = SRegList;
222
1.74k
    break;
223
2.37k
  case MVT::v4f16:
224
2.37k
  case MVT::f64:
225
2.37k
    RegList = DRegList;
226
2.37k
    break;
227
2.37k
  case MVT::v8f16:
228
301
  case MVT::v2f64:
229
301
    RegList = QRegList;
230
301
    break;
231
301
  default:
232
0
    llvm_unreachable("Unexpected member type for block aggregate");
233
301
    
break0
;
234
4.61k
  }
235
4.61k
236
4.61k
  unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
237
4.61k
  if (RegResult) {
238
4.44k
    for (SmallVectorImpl<CCValAssign>::iterator It = PendingMembers.begin();
239
9.15k
         It != PendingMembers.end(); 
++It4.71k
) {
240
4.71k
      It->convertToReg(RegResult);
241
4.71k
      State.addLoc(*It);
242
4.71k
      ++RegResult;
243
4.71k
    }
244
4.44k
    PendingMembers.clear();
245
4.44k
    return true;
246
4.44k
  }
247
163
248
163
  // Register allocation failed, we'll be needing the stack
249
163
  unsigned Size = LocVT.getSizeInBits() / 8;
250
163
  if (LocVT == MVT::i32 && 
State.getNextStackOffset() == 092
) {
251
79
    // If nothing else has used the stack until this point, a non-HFA aggregate
252
79
    // can be split between regs and stack.
253
79
    unsigned RegIdx = State.getFirstUnallocated(RegList);
254
242
    for (auto &It : PendingMembers) {
255
242
      if (RegIdx >= RegList.size())
256
125
        It.convertToMem(State.AllocateStack(Size, Size));
257
117
      else
258
117
        It.convertToReg(State.AllocateReg(RegList[RegIdx++]));
259
242
260
242
      State.addLoc(It);
261
242
    }
262
79
    PendingMembers.clear();
263
79
    return true;
264
84
  } else if (LocVT != MVT::i32)
265
71
    RegList = SRegList;
266
163
267
163
  // Mark all regs as unavailable (AAPCS rule C.2.vfp for VFP, C.6 for core)
268
163
  
for (auto Reg : RegList)84
269
1.18k
    State.AllocateReg(Reg);
270
84
271
84
  // After the first item has been allocated, the rest are packed as tightly as
272
84
  // possible. (E.g. an incoming i64 would have starting Align of 8, but we'll
273
84
  // be allocating a bunch of i32 slots).
274
84
  unsigned RestAlign = std::min(Align, Size);
275
84
276
134
  for (auto &It : PendingMembers) {
277
134
    It.convertToMem(State.AllocateStack(Size, Align));
278
134
    State.addLoc(It);
279
134
    Align = RestAlign;
280
134
  }
281
84
282
84
  // All pending members have now been allocated
283
84
  PendingMembers.clear();
284
84
285
84
  // This will be allocated by the last member of the aggregate
286
84
  return true;
287
163
}
288
289
} // End llvm namespace
290
291
#endif