1 | //===- AArch64GenRegisterBankInfo.def ----------------------------*- 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 | /// \file |
9 | /// This file defines all the static objects used by AArch64RegisterBankInfo. |
10 | /// \todo This should be generated by TableGen. |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | namespace llvm { |
14 | const RegisterBankInfo::PartialMapping AArch64GenRegisterBankInfo::PartMappings[]{ |
15 | /* StartIdx, Length, RegBank */ |
16 | // 0: FPR 16-bit value. |
17 | {0, 16, AArch64::FPRRegBank}, |
18 | // 1: FPR 32-bit value. |
19 | {0, 32, AArch64::FPRRegBank}, |
20 | // 2: FPR 64-bit value. |
21 | {0, 64, AArch64::FPRRegBank}, |
22 | // 3: FPR 128-bit value. |
23 | {0, 128, AArch64::FPRRegBank}, |
24 | // 4: FPR 256-bit value. |
25 | {0, 256, AArch64::FPRRegBank}, |
26 | // 5: FPR 512-bit value. |
27 | {0, 512, AArch64::FPRRegBank}, |
28 | // 6: GPR 32-bit value. |
29 | {0, 32, AArch64::GPRRegBank}, |
30 | // 7: GPR 64-bit value. |
31 | {0, 64, AArch64::GPRRegBank}, |
32 | // 8: GPR 128-bit value. |
33 | {0, 128, AArch64::GPRRegBank}, |
34 | }; |
35 | |
36 | // ValueMappings. |
37 | const RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{ |
38 | /* BreakDown, NumBreakDowns */ |
39 | // 0: invalid |
40 | {nullptr, 0}, |
41 | // 3-operands instructions (all binary operations should end up with one of |
42 | // those mapping). |
43 | // 1: FPR 16-bit value. <-- This must match First3OpsIdx. |
44 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, |
45 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, |
46 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, |
47 | // 4: FPR 32-bit value. <-- This must match First3OpsIdx. |
48 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, |
49 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, |
50 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, |
51 | // 7: FPR 64-bit value. |
52 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, |
53 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, |
54 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, |
55 | // 10: FPR 128-bit value. |
56 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1}, |
57 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1}, |
58 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1}, |
59 | // 13: FPR 256-bit value. |
60 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1}, |
61 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1}, |
62 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1}, |
63 | // 16: FPR 512-bit value. |
64 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1}, |
65 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1}, |
66 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1}, |
67 | // 19: GPR 32-bit value. |
68 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, |
69 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, |
70 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, |
71 | // 22: GPR 64-bit value. |
72 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, |
73 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, |
74 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, |
75 | // 25: GPR 128-bit value. <-- This must match Last3OpsIdx. |
76 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR128 - PMI_Min], 1}, |
77 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR128 - PMI_Min], 1}, |
78 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR128 - PMI_Min], 1}, |
79 | // Cross register bank copies. |
80 | // 28: FPR 16-bit value to GPR 16-bit. <-- This must match |
81 | // FirstCrossRegCpyIdx. |
82 | // Note: This is the kind of copy we see with physical registers. |
83 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, |
84 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, |
85 | // 30: FPR 32-bit value to GPR 32-bit value. |
86 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, |
87 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, |
88 | // 32: FPR 64-bit value to GPR 64-bit value. |
89 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, |
90 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, |
91 | // 34: FPR 128-bit value to GPR 128-bit value (invalid) |
92 | {nullptr, 1}, |
93 | {nullptr, 1}, |
94 | // 36: FPR 256-bit value to GPR 256-bit value (invalid) |
95 | {nullptr, 1}, |
96 | {nullptr, 1}, |
97 | // 38: FPR 512-bit value to GPR 512-bit value (invalid) |
98 | {nullptr, 1}, |
99 | {nullptr, 1}, |
100 | // 40: GPR 32-bit value to FPR 32-bit value. |
101 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, |
102 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, |
103 | // 42: GPR 64-bit value to FPR 64-bit value. <-- This must match |
104 | // LastCrossRegCpyIdx. |
105 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, |
106 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, |
107 | // 44: FPExt: 16 to 32. <-- This must match FPExt16To32Idx. |
108 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, |
109 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, |
110 | // 46: FPExt: 16 to 32. <-- This must match FPExt16To64Idx. |
111 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, |
112 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, |
113 | // 48: FPExt: 32 to 64. <-- This must match FPExt32To64Idx. |
114 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, |
115 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, |
116 | // 50: FPExt vector: 64 to 128. <-- This must match FPExt64To128Idx. |
117 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1}, |
118 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, |
119 | // 52: Shift scalar with 64 bit shift imm |
120 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, |
121 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, |
122 | {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, |
123 | }; |
124 | |
125 | bool AArch64GenRegisterBankInfo::checkPartialMap(unsigned Idx, |
126 | unsigned ValStartIdx, |
127 | unsigned ValLength, |
128 | const RegisterBank &RB) { |
129 | const PartialMapping &Map = PartMappings[Idx - PartialMappingIdx::PMI_Min]; |
130 | return Map.StartIdx == ValStartIdx && Map.Length == ValLength && |
131 | Map.RegBank == &RB; |
132 | } |
133 | |
134 | bool AArch64GenRegisterBankInfo::checkValueMapImpl(unsigned Idx, |
135 | unsigned FirstInBank, |
136 | unsigned Size, |
137 | unsigned Offset) { |
138 | unsigned PartialMapBaseIdx = Idx - PartialMappingIdx::PMI_Min; |
139 | const ValueMapping &Map = |
140 | AArch64GenRegisterBankInfo::getValueMapping(RBIdx: (PartialMappingIdx)FirstInBank, Size)[Offset]; |
141 | return Map.BreakDown == &PartMappings[PartialMapBaseIdx] && |
142 | Map.NumBreakDowns == 1; |
143 | } |
144 | |
145 | bool AArch64GenRegisterBankInfo::checkPartialMappingIdx( |
146 | PartialMappingIdx FirstAlias, PartialMappingIdx LastAlias, |
147 | ArrayRef<PartialMappingIdx> Order) { |
148 | if (Order.front() != FirstAlias) |
149 | return false; |
150 | if (Order.back() != LastAlias) |
151 | return false; |
152 | if (Order.front() > Order.back()) |
153 | return false; |
154 | |
155 | PartialMappingIdx Previous = Order.front(); |
156 | bool First = true; |
157 | for (const auto &Current : Order) { |
158 | if (First) { |
159 | First = false; |
160 | continue; |
161 | } |
162 | if (Previous + 1 != Current) |
163 | return false; |
164 | Previous = Current; |
165 | } |
166 | return true; |
167 | } |
168 | |
169 | unsigned AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(unsigned RBIdx, |
170 | unsigned Size) { |
171 | if (RBIdx == PMI_FirstGPR) { |
172 | if (Size <= 32) |
173 | return 0; |
174 | if (Size <= 64) |
175 | return 1; |
176 | if (Size <= 128) |
177 | return 2; |
178 | return -1; |
179 | } |
180 | if (RBIdx == PMI_FirstFPR) { |
181 | if (Size <= 16) |
182 | return 0; |
183 | if (Size <= 32) |
184 | return 1; |
185 | if (Size <= 64) |
186 | return 2; |
187 | if (Size <= 128) |
188 | return 3; |
189 | if (Size <= 256) |
190 | return 4; |
191 | if (Size <= 512) |
192 | return 5; |
193 | return -1; |
194 | } |
195 | return -1; |
196 | } |
197 | |
198 | const RegisterBankInfo::ValueMapping * |
199 | AArch64GenRegisterBankInfo::getValueMapping(PartialMappingIdx RBIdx, |
200 | unsigned Size) { |
201 | assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that" ); |
202 | unsigned BaseIdxOffset = getRegBankBaseIdxOffset(RBIdx, Size); |
203 | if (BaseIdxOffset == -1u) |
204 | return &ValMappings[InvalidIdx]; |
205 | |
206 | unsigned ValMappingIdx = |
207 | First3OpsIdx + (RBIdx - PartialMappingIdx::PMI_Min + BaseIdxOffset) * |
208 | ValueMappingIdx::DistanceBetweenRegBanks; |
209 | assert(ValMappingIdx >= First3OpsIdx && ValMappingIdx <= Last3OpsIdx && |
210 | "Mapping out of bound" ); |
211 | |
212 | return &ValMappings[ValMappingIdx]; |
213 | } |
214 | |
215 | const AArch64GenRegisterBankInfo::PartialMappingIdx |
216 | AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{ |
217 | PMI_None, // CCR |
218 | PMI_FirstFPR, // FPR |
219 | PMI_FirstGPR, // GPR |
220 | }; |
221 | |
222 | const RegisterBankInfo::ValueMapping * |
223 | AArch64GenRegisterBankInfo::getCopyMapping(unsigned DstBankID, |
224 | unsigned SrcBankID, unsigned Size) { |
225 | assert(DstBankID < AArch64::NumRegisterBanks && "Invalid bank ID" ); |
226 | assert(SrcBankID < AArch64::NumRegisterBanks && "Invalid bank ID" ); |
227 | PartialMappingIdx DstRBIdx = BankIDToCopyMapIdx[DstBankID]; |
228 | PartialMappingIdx SrcRBIdx = BankIDToCopyMapIdx[SrcBankID]; |
229 | assert(DstRBIdx != PMI_None && "No such mapping" ); |
230 | assert(SrcRBIdx != PMI_None && "No such mapping" ); |
231 | |
232 | if (DstRBIdx == SrcRBIdx) |
233 | return getValueMapping(RBIdx: DstRBIdx, Size); |
234 | |
235 | assert(Size <= 64 && "GPR cannot handle that size" ); |
236 | unsigned ValMappingIdx = |
237 | FirstCrossRegCpyIdx + |
238 | (DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(RBIdx: DstRBIdx, Size)) * |
239 | ValueMappingIdx::DistanceBetweenCrossRegCpy; |
240 | assert(ValMappingIdx >= FirstCrossRegCpyIdx && |
241 | ValMappingIdx <= LastCrossRegCpyIdx && "Mapping out of bound" ); |
242 | return &ValMappings[ValMappingIdx]; |
243 | } |
244 | |
245 | const RegisterBankInfo::ValueMapping * |
246 | AArch64GenRegisterBankInfo::getFPExtMapping(unsigned DstSize, |
247 | unsigned SrcSize) { |
248 | // We support: |
249 | // - For Scalar: |
250 | // - 16 to 32. |
251 | // - 16 to 64. |
252 | // - 32 to 64. |
253 | // => FPR 16 to FPR 32|64 |
254 | // => FPR 32 to FPR 64 |
255 | // - For vectors: |
256 | // - v4f16 to v4f32 |
257 | // - v2f32 to v2f64 |
258 | // => FPR 64 to FPR 128 |
259 | |
260 | // Check that we have been asked sensible sizes. |
261 | if (SrcSize == 16) { |
262 | assert((DstSize == 32 || DstSize == 64) && "Unexpected half extension" ); |
263 | if (DstSize == 32) |
264 | return &ValMappings[FPExt16To32Idx]; |
265 | return &ValMappings[FPExt16To64Idx]; |
266 | } |
267 | |
268 | if (SrcSize == 32) { |
269 | assert(DstSize == 64 && "Unexpected float extension" ); |
270 | return &ValMappings[FPExt32To64Idx]; |
271 | } |
272 | assert((SrcSize == 64 || DstSize == 128) && "Unexpected vector extension" ); |
273 | return &ValMappings[FPExt64To128Idx]; |
274 | } |
275 | } // End llvm namespace. |
276 | |