284 lines · plain
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-exception6//7//===----------------------------------------------------------------------===//8/// \file9/// 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: invalid40 {nullptr, 0},41 // 3-operands instructions (all binary operations should end up with one of42 // 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 match81 // 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 match104 // 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 imm120 {&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 (Size.isScalable())187 return 3;188 if (MinSize <= 16)189 return 0;190 if (MinSize <= 32)191 return 1;192 if (MinSize <= 64)193 return 2;194 if (MinSize <= 128)195 return 3;196 if (MinSize <= 256)197 return 4;198 if (MinSize <= 512)199 return 5;200 return -1;201 }202 return -1;203}204 205const RegisterBankInfo::ValueMapping *206AArch64GenRegisterBankInfo::getValueMapping(PartialMappingIdx RBIdx,207 const TypeSize Size) {208 assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that");209 unsigned BaseIdxOffset = getRegBankBaseIdxOffset(RBIdx, Size);210 if (BaseIdxOffset == -1u)211 return &ValMappings[InvalidIdx];212 213 unsigned ValMappingIdx =214 First3OpsIdx + (RBIdx - PartialMappingIdx::PMI_Min + BaseIdxOffset) *215 ValueMappingIdx::DistanceBetweenRegBanks;216 assert(ValMappingIdx >= First3OpsIdx && ValMappingIdx <= Last3OpsIdx &&217 "Mapping out of bound");218 219 return &ValMappings[ValMappingIdx];220}221 222const AArch64GenRegisterBankInfo::PartialMappingIdx223 AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{224 PMI_None, // CCR225 PMI_FirstFPR, // FPR226 PMI_FirstGPR, // GPR227 };228 229const RegisterBankInfo::ValueMapping *230AArch64GenRegisterBankInfo::getCopyMapping(unsigned DstBankID,231 unsigned SrcBankID,232 const TypeSize Size) {233 assert(DstBankID < AArch64::NumRegisterBanks && "Invalid bank ID");234 assert(SrcBankID < AArch64::NumRegisterBanks && "Invalid bank ID");235 PartialMappingIdx DstRBIdx = BankIDToCopyMapIdx[DstBankID];236 PartialMappingIdx SrcRBIdx = BankIDToCopyMapIdx[SrcBankID];237 assert(DstRBIdx != PMI_None && "No such mapping");238 assert(SrcRBIdx != PMI_None && "No such mapping");239 240 if (DstRBIdx == SrcRBIdx)241 return getValueMapping(DstRBIdx, Size);242 243 assert(Size <= 64 && "GPR cannot handle that size");244 unsigned ValMappingIdx =245 FirstCrossRegCpyIdx +246 (DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(DstRBIdx, Size)) *247 ValueMappingIdx::DistanceBetweenCrossRegCpy;248 assert(ValMappingIdx >= FirstCrossRegCpyIdx &&249 ValMappingIdx <= LastCrossRegCpyIdx && "Mapping out of bound");250 return &ValMappings[ValMappingIdx];251}252 253const RegisterBankInfo::ValueMapping *254AArch64GenRegisterBankInfo::getFPExtMapping(unsigned DstSize,255 unsigned SrcSize) {256 // We support:257 // - For Scalar:258 // - 16 to 32.259 // - 16 to 64.260 // - 32 to 64.261 // => FPR 16 to FPR 32|64262 // => FPR 32 to FPR 64263 // - For vectors:264 // - v4f16 to v4f32265 // - v2f32 to v2f64266 // => FPR 64 to FPR 128267 268 // Check that we have been asked sensible sizes.269 if (SrcSize == 16) {270 assert((DstSize == 32 || DstSize == 64) && "Unexpected half extension");271 if (DstSize == 32)272 return &ValMappings[FPExt16To32Idx];273 return &ValMappings[FPExt16To64Idx];274 }275 276 if (SrcSize == 32) {277 assert(DstSize == 64 && "Unexpected float extension");278 return &ValMappings[FPExt32To64Idx];279 }280 assert((SrcSize == 64 || DstSize == 128) && "Unexpected vector extension");281 return &ValMappings[FPExt64To128Idx];282}283} // End llvm namespace.284