//===- 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. //===----------------------------------------------------------------------===// #ifndef LLVM_BUILD_GLOBAL_ISEL #error "You shouldn't build this" #endif namespace llvm { namespace AArch64 { const uint32_t GPRCoverageData[] = { // Classes 0-31 (1u << AArch64::GPR32allRegClassID) | (1u << AArch64::GPR32RegClassID) | (1u << AArch64::GPR32spRegClassID) | (1u << AArch64::GPR32commonRegClassID) | (1u << AArch64::GPR32sponlyRegClassID) | (1u << AArch64::GPR64allRegClassID) | (1u << AArch64::GPR64RegClassID) | (1u << AArch64::GPR64spRegClassID) | (1u << AArch64::GPR64commonRegClassID) | (1u << AArch64::tcGPR64RegClassID) | (1u << AArch64::GPR64sponlyRegClassID), // Classes 32-63 0, // FIXME: The entries below this point can be safely removed once this is // tablegenerated. It's only needed because of the hardcoded register class // limit. // Classes 64-96 0, // Classes 97-128 0, // Classes 129-160 0, // Classes 161-192 0, // Classes 193-224 0, }; const uint32_t FPRCoverageData[] = { // Classes 0-31 (1u << AArch64::FPR8RegClassID) | (1u << AArch64::FPR16RegClassID) | (1u << AArch64::FPR32RegClassID) | (1u << AArch64::FPR64RegClassID) | (1u << AArch64::DDRegClassID) | (1u << AArch64::FPR128RegClassID) | (1u << AArch64::FPR128_loRegClassID) | (1u << AArch64::DDDRegClassID) | (1u << AArch64::DDDDRegClassID), // Classes 32-63 (1u << (AArch64::QQRegClassID - 32)) | (1u << (AArch64::QQ_with_qsub0_in_FPR128_loRegClassID - 32)) | (1u << (AArch64::QQ_with_qsub1_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQQ_with_qsub1_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | (1u << (AArch64::QQQQRegClassID - 32)) | (1u << (AArch64::QQQQ_with_qsub0_in_FPR128_loRegClassID - 32)) | (1u << (AArch64::QQQQ_with_qsub1_in_FPR128_loRegClassID - 32)) | (1u << (AArch64::QQQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | (1u << (AArch64::QQQQ_with_qsub3_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub1_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQQQ_with_qsub2_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQ_with_qsub0_in_FPR128_lo_and_QQ_with_qsub1_in_FPR128_loRegClassID - 32)) | (1u << (AArch64::QQQRegClassID - 32)) | (1u << (AArch64::QQQ_with_qsub0_in_FPR128_loRegClassID - 32)) | (1u << (AArch64::QQQ_with_qsub1_in_FPR128_loRegClassID - 32)) | (1u << (AArch64::QQQ_with_qsub2_in_FPR128_loRegClassID - 32)) | (1u << (AArch64:: QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub1_in_FPR128_loRegClassID - 32)), // FIXME: The entries below this point can be safely removed once this // is tablegenerated. It's only needed because of the hardcoded register // class limit. // Classes 64-96 0, // Classes 97-128 0, // Classes 129-160 0, // Classes 161-192 0, // Classes 193-224 0, }; const uint32_t CCRCoverageData[] = { // Classes 0-31 1u << AArch64::CCRRegClassID, // Classes 32-63 0, // FIXME: The entries below this point can be safely removed once this // is tablegenerated. It's only needed because of the hardcoded register // class limit. // Classes 64-96 0, // Classes 97-128 0, // Classes 129-160 0, // Classes 161-192 0, // Classes 193-224 0, }; RegisterBank GPRRegBank(AArch64::GPRRegBankID, "GPR", 64, GPRCoverageData); RegisterBank FPRRegBank(AArch64::FPRRegBankID, "FPR", 512, FPRCoverageData); RegisterBank CCRRegBank(AArch64::CCRRegBankID, "CCR", 32, CCRCoverageData); RegisterBank *RegBanks[] = {&GPRRegBank, &FPRRegBank, &CCRRegBank}; // PartialMappings. enum PartialMappingIdx { PMI_None = -1, PMI_GPR32 = 1, PMI_GPR64, PMI_FPR32, PMI_FPR64, PMI_FPR128, PMI_FPR256, PMI_FPR512, PMI_FirstGPR = PMI_GPR32, PMI_LastGPR = PMI_GPR64, PMI_FirstFPR = PMI_FPR32, PMI_LastFPR = PMI_FPR512, PMI_Min = PMI_FirstGPR, }; static unsigned getRegBankBaseIdxOffset(unsigned Size) { assert(Size && "0-sized type!!"); // Make anything smaller than 32 gets 32 Size = ((Size + 31) / 32) * 32; // 32 is 0, 64 is 1, 128 is 2, and so on. return Log2_32(Size) - /*Log2_32(32)=*/ 5; } RegisterBankInfo::PartialMapping PartMappings[] { /* StartIdx, Length, RegBank */ // 0: GPR 32-bit value. {0, 32, GPRRegBank}, // 1: GPR 64-bit value. {0, 64, GPRRegBank}, // 2: FPR 32-bit value. {0, 32, FPRRegBank}, // 3: FPR 64-bit value. {0, 64, FPRRegBank}, // 4: FPR 128-bit value. {0, 128, FPRRegBank}, // 5: FPR 256-bit value. {0, 256, FPRRegBank}, // 6: FPR 512-bit value. {0, 512, FPRRegBank} }; enum ValueMappingIdx { First3OpsIdx = 0, Last3OpsIdx = 18, DistanceBetweenRegBanks = 3, FirstCrossRegCpyIdx = 21, LastCrossRegCpyIdx = 27, DistanceBetweenCrossRegCpy = 2 }; // ValueMappings. RegisterBankInfo::ValueMapping ValMappings[]{ /* BreakDown, NumBreakDowns */ // 3-operands instructions (all binary operations should end up with one of // those mapping). // 0: GPR 32-bit value. <-- This must match First3OpsIdx. {&PartMappings[PMI_GPR32 - PMI_Min], 1}, {&PartMappings[PMI_GPR32 - PMI_Min], 1}, {&PartMappings[PMI_GPR32 - PMI_Min], 1}, // 3: GPR 64-bit value. {&PartMappings[PMI_GPR64 - PMI_Min], 1}, {&PartMappings[PMI_GPR64 - PMI_Min], 1}, {&PartMappings[PMI_GPR64 - PMI_Min], 1}, // 6: FPR 32-bit value. {&PartMappings[PMI_FPR32 - PMI_Min], 1}, {&PartMappings[PMI_FPR32 - PMI_Min], 1}, {&PartMappings[PMI_FPR32 - PMI_Min], 1}, // 9: FPR 64-bit value. {&PartMappings[PMI_FPR64 - PMI_Min], 1}, {&PartMappings[PMI_FPR64 - PMI_Min], 1}, {&PartMappings[PMI_FPR64 - PMI_Min], 1}, // 12: FPR 128-bit value. {&PartMappings[PMI_FPR128 - PMI_Min], 1}, {&PartMappings[PMI_FPR128 - PMI_Min], 1}, {&PartMappings[PMI_FPR128 - PMI_Min], 1}, // 15: FPR 256-bit value. {&PartMappings[PMI_FPR256 - PMI_Min], 1}, {&PartMappings[PMI_FPR256 - PMI_Min], 1}, {&PartMappings[PMI_FPR256 - PMI_Min], 1}, // 18: FPR 512-bit value. <-- This must match Last3OpsIdx. {&PartMappings[PMI_FPR512 - PMI_Min], 1}, {&PartMappings[PMI_FPR512 - PMI_Min], 1}, {&PartMappings[PMI_FPR512 - PMI_Min], 1}, // Cross register bank copies. // 21: GPR 32-bit value to FPR 32-bit value. <-- This must match // FirstCrossRegCpyIdx. {&PartMappings[PMI_GPR32 - PMI_Min], 1}, {&PartMappings[PMI_FPR32 - PMI_Min], 1}, // 23: GPR 64-bit value to FPR 64-bit value. {&PartMappings[PMI_GPR64 - PMI_Min], 1}, {&PartMappings[PMI_FPR64 - PMI_Min], 1}, // 25: FPR 32-bit value to GPR 32-bit value. {&PartMappings[PMI_FPR32 - PMI_Min], 1}, {&PartMappings[PMI_GPR32 - PMI_Min], 1}, // 27: FPR 64-bit value to GPR 64-bit value. <-- This must match // LastCrossRegCpyIdx. {&PartMappings[PMI_FPR64 - PMI_Min], 1}, {&PartMappings[PMI_GPR64 - PMI_Min], 1} }; /// Get the pointer to the ValueMapping representing the RegisterBank /// at \p RBIdx with a size of \p Size. /// /// The returned mapping works for instructions with the same kind of /// operands for up to 3 operands. /// /// \pre \p RBIdx != PartialMappingIdx::None const RegisterBankInfo::ValueMapping * getValueMapping(PartialMappingIdx RBIdx, unsigned Size) { assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that"); unsigned ValMappingIdx = First3OpsIdx + (RBIdx - AArch64::PartialMappingIdx::PMI_Min + getRegBankBaseIdxOffset(Size)) * ValueMappingIdx::DistanceBetweenRegBanks; assert(ValMappingIdx >= AArch64::First3OpsIdx && ValMappingIdx <= AArch64::Last3OpsIdx && "Mapping out of bound"); return &ValMappings[ValMappingIdx]; } /// Get the pointer to the ValueMapping of the operands of a copy /// instruction from a GPR or FPR register to a GPR or FPR register /// with a size of \p Size. /// /// If \p DstIsGPR is true, the destination of the copy is on GPR, /// otherwise it is on FPR. Same thing for \p SrcIsGPR. const RegisterBankInfo::ValueMapping * getCopyMapping(bool DstIsGPR, bool SrcIsGPR, unsigned Size) { PartialMappingIdx DstRBIdx = DstIsGPR ? PMI_FirstGPR : PMI_FirstFPR; PartialMappingIdx SrcRBIdx = SrcIsGPR ? PMI_FirstGPR : PMI_FirstFPR; if (DstRBIdx == SrcRBIdx) return getValueMapping(DstRBIdx, Size); assert(Size <= 64 && "GPR cannot handle that size"); unsigned ValMappingIdx = FirstCrossRegCpyIdx + (DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(Size)) * ValueMappingIdx::DistanceBetweenCrossRegCpy; assert(ValMappingIdx >= AArch64::FirstCrossRegCpyIdx && ValMappingIdx <= AArch64::LastCrossRegCpyIdx && "Mapping out of bound"); return &ValMappings[ValMappingIdx]; } } // End AArch64 namespace. } // End llvm namespace.