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