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