//===- AArch64GenRegisterBankInfo.def ----------------------------*- C++ -*-==// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// \file /// This file defines all the static objects used by AArch64RegisterBankInfo. /// \todo This should be generated by TableGen. //===----------------------------------------------------------------------===// namespace llvm { RegisterBankInfo::PartialMapping AArch64GenRegisterBankInfo::PartMappings[]{ /* StartIdx, Length, RegBank */ // 0: FPR 16-bit value. {0, 16, AArch64::FPRRegBank}, // 1: FPR 32-bit value. {0, 32, AArch64::FPRRegBank}, // 2: FPR 64-bit value. {0, 64, AArch64::FPRRegBank}, // 3: FPR 128-bit value. {0, 128, AArch64::FPRRegBank}, // 4: FPR 256-bit value. {0, 256, AArch64::FPRRegBank}, // 5: FPR 512-bit value. {0, 512, AArch64::FPRRegBank}, // 6: GPR 32-bit value. {0, 32, AArch64::GPRRegBank}, // 7: GPR 64-bit value. {0, 64, AArch64::GPRRegBank}, }; // ValueMappings. RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{ /* BreakDown, NumBreakDowns */ // 0: invalid {nullptr, 0}, // 3-operands instructions (all binary operations should end up with one of // those mapping). // 1: FPR 16-bit value. <-- This must match First3OpsIdx. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, // 4: FPR 32-bit value. <-- This must match First3OpsIdx. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, // 7: FPR 64-bit value. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, // 10: FPR 128-bit value. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1}, // 13: FPR 256-bit value. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1}, // 16: FPR 512-bit value. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1}, // 19: GPR 32-bit value. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, // 22: GPR 64-bit value. <-- This must match Last3OpsIdx. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, // Cross register bank copies. // 25: FPR 16-bit value to GPR 16-bit (invalid). <-- This must match // FirstCrossRegCpyIdx. {nullptr, 1}, {nullptr, 1}, // 27: FPR 32-bit value to GPR 32-bit value. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, // 29: FPR 64-bit value to GPR 64-bit value. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, // 31: FPR 128-bit value to GPR 128-bit value (invalid) {nullptr, 1}, {nullptr, 1}, // 33: FPR 256-bit value to GPR 256-bit value (invalid) {nullptr, 1}, {nullptr, 1}, // 35: FPR 512-bit value to GPR 512-bit value (invalid) {nullptr, 1}, {nullptr, 1}, // 37: GPR 32-bit value to FPR 32-bit value. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, // 39: GPR 64-bit value to FPR 64-bit value. <-- This must match // LastCrossRegCpyIdx. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, // 41: FPExt: 16 to 32. <-- This must match FPExt16To32Idx. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, // 43: FPExt: 16 to 32. <-- This must match FPExt16To64Idx. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1}, // 45: FPExt: 32 to 64. <-- This must match FPExt32To64Idx. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1}, // 47: FPExt vector: 64 to 128. <-- This must match FPExt64To128Idx. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1}, {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1}, }; bool AArch64GenRegisterBankInfo::checkPartialMap(unsigned Idx, unsigned ValStartIdx, unsigned ValLength, const RegisterBank &RB) { const PartialMapping &Map = PartMappings[Idx - PartialMappingIdx::PMI_Min]; return Map.StartIdx == ValStartIdx && Map.Length == ValLength && Map.RegBank == &RB; } bool AArch64GenRegisterBankInfo::checkValueMapImpl(unsigned Idx, unsigned FirstInBank, unsigned Size, unsigned Offset) { unsigned PartialMapBaseIdx = Idx - PartialMappingIdx::PMI_Min; const ValueMapping &Map = AArch64GenRegisterBankInfo::getValueMapping((PartialMappingIdx)FirstInBank, Size)[Offset]; return Map.BreakDown == &PartMappings[PartialMapBaseIdx] && Map.NumBreakDowns == 1; } bool AArch64GenRegisterBankInfo::checkPartialMappingIdx( PartialMappingIdx FirstAlias, PartialMappingIdx LastAlias, ArrayRef Order) { if (Order.front() != FirstAlias) return false; if (Order.back() != LastAlias) return false; if (Order.front() > Order.back()) return false; PartialMappingIdx Previous = Order.front(); bool First = true; for (const auto &Current : Order) { if (First) { First = false; continue; } if (Previous + 1 != Current) return false; Previous = Current; } return true; } unsigned AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(unsigned RBIdx, unsigned Size) { if (RBIdx == PMI_FirstGPR) { if (Size <= 32) return 0; if (Size <= 64) return 1; return -1; } if (RBIdx == PMI_FirstFPR) { if (Size <= 16) return 0; if (Size <= 32) return 1; if (Size <= 64) return 2; if (Size <= 128) return 3; if (Size <= 256) return 4; if (Size <= 512) return 5; return -1; } return -1; } const RegisterBankInfo::ValueMapping * AArch64GenRegisterBankInfo::getValueMapping(PartialMappingIdx RBIdx, unsigned Size) { assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that"); unsigned BaseIdxOffset = getRegBankBaseIdxOffset(RBIdx, Size); if (BaseIdxOffset == -1u) return &ValMappings[InvalidIdx]; unsigned ValMappingIdx = First3OpsIdx + (RBIdx - PartialMappingIdx::PMI_Min + BaseIdxOffset) * ValueMappingIdx::DistanceBetweenRegBanks; assert(ValMappingIdx >= First3OpsIdx && ValMappingIdx <= Last3OpsIdx && "Mapping out of bound"); return &ValMappings[ValMappingIdx]; } AArch64GenRegisterBankInfo::PartialMappingIdx AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{ PMI_None, // CCR PMI_FirstFPR, // FPR PMI_FirstGPR, // GPR }; const RegisterBankInfo::ValueMapping * AArch64GenRegisterBankInfo::getCopyMapping(unsigned DstBankID, unsigned SrcBankID, unsigned Size) { assert(DstBankID < AArch64::NumRegisterBanks && "Invalid bank ID"); assert(SrcBankID < AArch64::NumRegisterBanks && "Invalid bank ID"); PartialMappingIdx DstRBIdx = BankIDToCopyMapIdx[DstBankID]; PartialMappingIdx SrcRBIdx = BankIDToCopyMapIdx[SrcBankID]; assert(DstRBIdx != PMI_None && "No such mapping"); assert(SrcRBIdx != PMI_None && "No such mapping"); if (DstRBIdx == SrcRBIdx) return getValueMapping(DstRBIdx, Size); assert(Size <= 64 && "GPR cannot handle that size"); unsigned ValMappingIdx = FirstCrossRegCpyIdx + (DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(DstRBIdx, Size)) * ValueMappingIdx::DistanceBetweenCrossRegCpy; assert(ValMappingIdx >= FirstCrossRegCpyIdx && ValMappingIdx <= LastCrossRegCpyIdx && "Mapping out of bound"); return &ValMappings[ValMappingIdx]; } const RegisterBankInfo::ValueMapping * AArch64GenRegisterBankInfo::getFPExtMapping(unsigned DstSize, unsigned SrcSize) { // We support: // - For Scalar: // - 16 to 32. // - 16 to 64. // - 32 to 64. // => FPR 16 to FPR 32|64 // => FPR 32 to FPR 64 // - For vectors: // - v4f16 to v4f32 // - v2f32 to v2f64 // => FPR 64 to FPR 128 // Check that we have been asked sensible sizes. if (SrcSize == 16) { assert((DstSize == 32 || DstSize == 64) && "Unexpected half extension"); if (DstSize == 32) return &ValMappings[FPExt16To32Idx]; return &ValMappings[FPExt16To64Idx]; } if (SrcSize == 32) { assert(DstSize == 64 && "Unexpected float extension"); return &ValMappings[FPExt32To64Idx]; } assert((SrcSize == 64 || DstSize == 128) && "Unexpected vector extension"); return &ValMappings[FPExt64To128Idx]; } } // End llvm namespace.