]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def
Merge ^/head r326936 through r327149.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / AArch64 / AArch64GenRegisterBankInfo.def
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
14 namespace llvm {
15 RegisterBankInfo::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.
36 RegisterBankInfo::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
116 bool 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
125 bool 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
136 bool 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
160 unsigned 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
187 const RegisterBankInfo::ValueMapping *
188 AArch64GenRegisterBankInfo::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
204 AArch64GenRegisterBankInfo::PartialMappingIdx
205     AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{
206         PMI_None,     // CCR
207         PMI_FirstFPR, // FPR
208         PMI_FirstGPR, // GPR
209     };
210
211 const RegisterBankInfo::ValueMapping *
212 AArch64GenRegisterBankInfo::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
234 const RegisterBankInfo::ValueMapping *
235 AArch64GenRegisterBankInfo::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.