xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 {
14const 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.
37const 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
125bool 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
134bool 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(
141        (PartialMappingIdx)FirstInBank,
142        TypeSize::getFixed(Size))[Offset];
143  return Map.BreakDown == &PartMappings[PartialMapBaseIdx] &&
144         Map.NumBreakDowns == 1;
145}
146
147bool AArch64GenRegisterBankInfo::checkPartialMappingIdx(
148    PartialMappingIdx FirstAlias, PartialMappingIdx LastAlias,
149    ArrayRef<PartialMappingIdx> Order) {
150  if (Order.front() != FirstAlias)
151    return false;
152  if (Order.back() != LastAlias)
153    return false;
154  if (Order.front() > Order.back())
155    return false;
156
157  PartialMappingIdx Previous = Order.front();
158  bool First = true;
159  for (const auto &Current : Order) {
160    if (First) {
161      First = false;
162      continue;
163    }
164    if (Previous + 1 != Current)
165      return false;
166    Previous = Current;
167  }
168  return true;
169}
170
171unsigned AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(unsigned RBIdx,
172                                                             TypeSize Size) {
173  if (RBIdx == PMI_FirstGPR) {
174    if (Size <= 32)
175      return 0;
176    if (Size <= 64)
177      return 1;
178    if (Size <= 128)
179      return 2;
180    return -1;
181  }
182  if (RBIdx == PMI_FirstFPR) {
183    const unsigned MinSize = Size.getKnownMinValue();
184    assert((!Size.isScalable() || MinSize >= 128) &&
185           "Scalable vector types should have size of at least 128 bits");
186    if (MinSize <= 16)
187      return 0;
188    if (MinSize <= 32)
189      return 1;
190    if (MinSize <= 64)
191      return 2;
192    if (MinSize <= 128)
193      return 3;
194    if (MinSize <= 256)
195      return 4;
196    if (MinSize <= 512)
197      return 5;
198    return -1;
199  }
200  return -1;
201}
202
203const RegisterBankInfo::ValueMapping *
204AArch64GenRegisterBankInfo::getValueMapping(PartialMappingIdx RBIdx,
205                                            const TypeSize Size) {
206  assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that");
207  unsigned BaseIdxOffset = getRegBankBaseIdxOffset(RBIdx, Size);
208  if (BaseIdxOffset == -1u)
209    return &ValMappings[InvalidIdx];
210
211  unsigned ValMappingIdx =
212      First3OpsIdx + (RBIdx - PartialMappingIdx::PMI_Min + BaseIdxOffset) *
213                         ValueMappingIdx::DistanceBetweenRegBanks;
214  assert(ValMappingIdx >= First3OpsIdx && ValMappingIdx <= Last3OpsIdx &&
215         "Mapping out of bound");
216
217  return &ValMappings[ValMappingIdx];
218}
219
220const AArch64GenRegisterBankInfo::PartialMappingIdx
221    AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{
222        PMI_None,     // CCR
223        PMI_FirstFPR, // FPR
224        PMI_FirstGPR, // GPR
225    };
226
227const RegisterBankInfo::ValueMapping *
228AArch64GenRegisterBankInfo::getCopyMapping(unsigned DstBankID,
229                                           unsigned SrcBankID,
230                                           const TypeSize Size) {
231  assert(DstBankID < AArch64::NumRegisterBanks && "Invalid bank ID");
232  assert(SrcBankID < AArch64::NumRegisterBanks && "Invalid bank ID");
233  PartialMappingIdx DstRBIdx = BankIDToCopyMapIdx[DstBankID];
234  PartialMappingIdx SrcRBIdx = BankIDToCopyMapIdx[SrcBankID];
235  assert(DstRBIdx != PMI_None && "No such mapping");
236  assert(SrcRBIdx != PMI_None && "No such mapping");
237
238  if (DstRBIdx == SrcRBIdx)
239    return getValueMapping(DstRBIdx, Size);
240
241  assert(Size <= 64 && "GPR cannot handle that size");
242  unsigned ValMappingIdx =
243      FirstCrossRegCpyIdx +
244      (DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(DstRBIdx, Size)) *
245          ValueMappingIdx::DistanceBetweenCrossRegCpy;
246  assert(ValMappingIdx >= FirstCrossRegCpyIdx &&
247         ValMappingIdx <= LastCrossRegCpyIdx && "Mapping out of bound");
248  return &ValMappings[ValMappingIdx];
249}
250
251const RegisterBankInfo::ValueMapping *
252AArch64GenRegisterBankInfo::getFPExtMapping(unsigned DstSize,
253                                         unsigned SrcSize) {
254  // We support:
255  // - For Scalar:
256  //   - 16 to 32.
257  //   - 16 to 64.
258  //   - 32 to 64.
259  // => FPR 16 to FPR 32|64
260  // => FPR 32 to FPR 64
261  // - For vectors:
262  //   - v4f16 to v4f32
263  //   - v2f32 to v2f64
264  // => FPR 64 to FPR 128
265
266  // Check that we have been asked sensible sizes.
267  if (SrcSize == 16) {
268    assert((DstSize == 32 || DstSize == 64) && "Unexpected half extension");
269    if (DstSize == 32)
270      return &ValMappings[FPExt16To32Idx];
271    return &ValMappings[FPExt16To64Idx];
272  }
273
274  if (SrcSize == 32) {
275    assert(DstSize == 64 && "Unexpected float extension");
276    return &ValMappings[FPExt32To64Idx];
277  }
278  assert((SrcSize == 64 || DstSize == 128) && "Unexpected vector extension");
279  return &ValMappings[FPExt64To128Idx];
280}
281} // End llvm namespace.
282