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