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