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