1 //===- AArch64GenRegisterBankInfo.def ----------------------------*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file defines all the static objects used by AArch64RegisterBankInfo.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_BUILD_GLOBAL_ISEL
15 #error "You shouldn't build this"
21 const uint32_t GPRCoverageData[] = {
23 (1u << AArch64::GPR32allRegClassID) | (1u << AArch64::GPR32RegClassID) |
24 (1u << AArch64::GPR32spRegClassID) |
25 (1u << AArch64::GPR32commonRegClassID) |
26 (1u << AArch64::GPR32sponlyRegClassID) |
27 (1u << AArch64::GPR64allRegClassID) | (1u << AArch64::GPR64RegClassID) |
28 (1u << AArch64::GPR64spRegClassID) |
29 (1u << AArch64::GPR64commonRegClassID) |
30 (1u << AArch64::tcGPR64RegClassID) |
31 (1u << AArch64::GPR64sponlyRegClassID),
34 // FIXME: The entries below this point can be safely removed once this is
35 // tablegenerated. It's only needed because of the hardcoded register class
49 const uint32_t FPRCoverageData[] = {
51 (1u << AArch64::FPR8RegClassID) | (1u << AArch64::FPR16RegClassID) |
52 (1u << AArch64::FPR32RegClassID) | (1u << AArch64::FPR64RegClassID) |
53 (1u << AArch64::DDRegClassID) | (1u << AArch64::FPR128RegClassID) |
54 (1u << AArch64::FPR128_loRegClassID) | (1u << AArch64::DDDRegClassID) |
55 (1u << AArch64::DDDDRegClassID),
57 (1u << (AArch64::QQRegClassID - 32)) |
58 (1u << (AArch64::QQ_with_qsub0_in_FPR128_loRegClassID - 32)) |
59 (1u << (AArch64::QQ_with_qsub1_in_FPR128_loRegClassID - 32)) |
62 QQQ_with_qsub1_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID -
66 QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID -
68 (1u << (AArch64::QQQQRegClassID - 32)) |
69 (1u << (AArch64::QQQQ_with_qsub0_in_FPR128_loRegClassID - 32)) |
70 (1u << (AArch64::QQQQ_with_qsub1_in_FPR128_loRegClassID - 32)) |
71 (1u << (AArch64::QQQQ_with_qsub2_in_FPR128_loRegClassID - 32)) |
72 (1u << (AArch64::QQQQ_with_qsub3_in_FPR128_loRegClassID - 32)) |
75 QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub1_in_FPR128_loRegClassID -
79 QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID -
83 QQQQ_with_qsub2_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID -
87 QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID -
91 QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID -
95 QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID -
99 QQ_with_qsub0_in_FPR128_lo_and_QQ_with_qsub1_in_FPR128_loRegClassID -
101 (1u << (AArch64::QQQRegClassID - 32)) |
102 (1u << (AArch64::QQQ_with_qsub0_in_FPR128_loRegClassID - 32)) |
103 (1u << (AArch64::QQQ_with_qsub1_in_FPR128_loRegClassID - 32)) |
104 (1u << (AArch64::QQQ_with_qsub2_in_FPR128_loRegClassID - 32)) |
107 QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub1_in_FPR128_loRegClassID -
109 // FIXME: The entries below this point can be safely removed once this
110 // is tablegenerated. It's only needed because of the hardcoded register
124 const uint32_t CCRCoverageData[] = {
126 1u << AArch64::CCRRegClassID,
129 // FIXME: The entries below this point can be safely removed once this
130 // is tablegenerated. It's only needed because of the hardcoded register
144 RegisterBank GPRRegBank(AArch64::GPRRegBankID, "GPR", 64, GPRCoverageData);
145 RegisterBank FPRRegBank(AArch64::FPRRegBankID, "FPR", 512, FPRCoverageData);
146 RegisterBank CCRRegBank(AArch64::CCRRegBankID, "CCR", 32, CCRCoverageData);
148 RegisterBank *RegBanks[] = {&GPRRegBank, &FPRRegBank, &CCRRegBank};
151 enum PartialMappingIdx {
160 PMI_FirstGPR = PMI_GPR32,
161 PMI_LastGPR = PMI_GPR64,
162 PMI_FirstFPR = PMI_FPR32,
163 PMI_LastFPR = PMI_FPR512,
164 PMI_Min = PMI_FirstGPR,
167 static unsigned getRegBankBaseIdxOffset(unsigned Size) {
168 assert(Size && "0-sized type!!");
169 // Make anything smaller than 32 gets 32
170 Size = ((Size + 31) / 32) * 32;
171 // 32 is 0, 64 is 1, 128 is 2, and so on.
172 return Log2_32(Size) - /*Log2_32(32)=*/ 5;
175 RegisterBankInfo::PartialMapping PartMappings[] {
176 /* StartIdx, Length, RegBank */
177 // 0: GPR 32-bit value.
179 // 1: GPR 64-bit value.
181 // 2: FPR 32-bit value.
183 // 3: FPR 64-bit value.
185 // 4: FPR 128-bit value.
186 {0, 128, FPRRegBank},
187 // 5: FPR 256-bit value.
188 {0, 256, FPRRegBank},
189 // 6: FPR 512-bit value.
193 enum ValueMappingIdx {
196 DistanceBetweenRegBanks = 3,
197 FirstCrossRegCpyIdx = 21,
198 LastCrossRegCpyIdx = 27,
199 DistanceBetweenCrossRegCpy = 2
203 RegisterBankInfo::ValueMapping ValMappings[]{
204 /* BreakDown, NumBreakDowns */
205 // 3-operands instructions (all binary operations should end up with one of
207 // 0: GPR 32-bit value. <-- This must match First3OpsIdx.
208 {&PartMappings[PMI_GPR32 - PMI_Min], 1},
209 {&PartMappings[PMI_GPR32 - PMI_Min], 1},
210 {&PartMappings[PMI_GPR32 - PMI_Min], 1},
211 // 3: GPR 64-bit value.
212 {&PartMappings[PMI_GPR64 - PMI_Min], 1},
213 {&PartMappings[PMI_GPR64 - PMI_Min], 1},
214 {&PartMappings[PMI_GPR64 - PMI_Min], 1},
215 // 6: FPR 32-bit value.
216 {&PartMappings[PMI_FPR32 - PMI_Min], 1},
217 {&PartMappings[PMI_FPR32 - PMI_Min], 1},
218 {&PartMappings[PMI_FPR32 - PMI_Min], 1},
219 // 9: FPR 64-bit value.
220 {&PartMappings[PMI_FPR64 - PMI_Min], 1},
221 {&PartMappings[PMI_FPR64 - PMI_Min], 1},
222 {&PartMappings[PMI_FPR64 - PMI_Min], 1},
223 // 12: FPR 128-bit value.
224 {&PartMappings[PMI_FPR128 - PMI_Min], 1},
225 {&PartMappings[PMI_FPR128 - PMI_Min], 1},
226 {&PartMappings[PMI_FPR128 - PMI_Min], 1},
227 // 15: FPR 256-bit value.
228 {&PartMappings[PMI_FPR256 - PMI_Min], 1},
229 {&PartMappings[PMI_FPR256 - PMI_Min], 1},
230 {&PartMappings[PMI_FPR256 - PMI_Min], 1},
231 // 18: FPR 512-bit value. <-- This must match Last3OpsIdx.
232 {&PartMappings[PMI_FPR512 - PMI_Min], 1},
233 {&PartMappings[PMI_FPR512 - PMI_Min], 1},
234 {&PartMappings[PMI_FPR512 - PMI_Min], 1},
235 // Cross register bank copies.
236 // 21: GPR 32-bit value to FPR 32-bit value. <-- This must match
237 // FirstCrossRegCpyIdx.
238 {&PartMappings[PMI_GPR32 - PMI_Min], 1},
239 {&PartMappings[PMI_FPR32 - PMI_Min], 1},
240 // 23: GPR 64-bit value to FPR 64-bit value.
241 {&PartMappings[PMI_GPR64 - PMI_Min], 1},
242 {&PartMappings[PMI_FPR64 - PMI_Min], 1},
243 // 25: FPR 32-bit value to GPR 32-bit value.
244 {&PartMappings[PMI_FPR32 - PMI_Min], 1},
245 {&PartMappings[PMI_GPR32 - PMI_Min], 1},
246 // 27: FPR 64-bit value to GPR 64-bit value. <-- This must match
247 // LastCrossRegCpyIdx.
248 {&PartMappings[PMI_FPR64 - PMI_Min], 1},
249 {&PartMappings[PMI_GPR64 - PMI_Min], 1}
252 /// Get the pointer to the ValueMapping representing the RegisterBank
253 /// at \p RBIdx with a size of \p Size.
255 /// The returned mapping works for instructions with the same kind of
256 /// operands for up to 3 operands.
258 /// \pre \p RBIdx != PartialMappingIdx::None
259 const RegisterBankInfo::ValueMapping *
260 getValueMapping(PartialMappingIdx RBIdx, unsigned Size) {
261 assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that");
262 unsigned ValMappingIdx = First3OpsIdx +
263 (RBIdx - AArch64::PartialMappingIdx::PMI_Min +
264 getRegBankBaseIdxOffset(Size)) *
265 ValueMappingIdx::DistanceBetweenRegBanks;
266 assert(ValMappingIdx >= AArch64::First3OpsIdx &&
267 ValMappingIdx <= AArch64::Last3OpsIdx && "Mapping out of bound");
269 return &ValMappings[ValMappingIdx];
272 /// Get the pointer to the ValueMapping of the operands of a copy
273 /// instruction from a GPR or FPR register to a GPR or FPR register
274 /// with a size of \p Size.
276 /// If \p DstIsGPR is true, the destination of the copy is on GPR,
277 /// otherwise it is on FPR. Same thing for \p SrcIsGPR.
278 const RegisterBankInfo::ValueMapping *
279 getCopyMapping(bool DstIsGPR, bool SrcIsGPR, unsigned Size) {
280 PartialMappingIdx DstRBIdx = DstIsGPR ? PMI_FirstGPR : PMI_FirstFPR;
281 PartialMappingIdx SrcRBIdx = SrcIsGPR ? PMI_FirstGPR : PMI_FirstFPR;
282 if (DstRBIdx == SrcRBIdx)
283 return getValueMapping(DstRBIdx, Size);
284 assert(Size <= 64 && "GPR cannot handle that size");
285 unsigned ValMappingIdx =
286 FirstCrossRegCpyIdx +
287 (DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(Size)) *
288 ValueMappingIdx::DistanceBetweenCrossRegCpy;
289 assert(ValMappingIdx >= AArch64::FirstCrossRegCpyIdx &&
290 ValMappingIdx <= AArch64::LastCrossRegCpyIdx &&
291 "Mapping out of bound");
292 return &ValMappings[ValMappingIdx];
295 } // End AArch64 namespace.
296 } // End llvm namespace.