diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def | 40 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp | 30 |
2 files changed, 68 insertions, 2 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def b/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def index 88dac21bab3..621bd14cc5f 100644 --- a/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def +++ b/llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def @@ -69,7 +69,10 @@ RegisterBankInfo::PartialMapping PartMappings[] { enum ValueMappingIdx { First3OpsIdx = 0, Last3OpsIdx = 18, - DistanceBetweenRegBanks = 3 + DistanceBetweenRegBanks = 3, + FirstCrossRegCpyIdx = 21, + LastCrossRegCpyIdx = 27, + DistanceBetweenCrossRegCpy = 2 }; // ValueMappings. @@ -90,7 +93,17 @@ RegisterBankInfo::ValueMapping ValMappings[] { // 15: FPR 256-bit value. {&PartMappings[5], 1}, {&PartMappings[5], 1}, {&PartMappings[5], 1}, // 18: FPR 512-bit value. <-- This must match Last3OpsIdx. - {&PartMappings[6], 1}, {&PartMappings[6], 1}, {&PartMappings[6], 1} + {&PartMappings[6], 1}, {&PartMappings[6], 1}, {&PartMappings[6], 1}, + // Cross register bank copies. + // 21: GPR 32-bit value to FPR 32-bit value. <-- This must match FirstCrossRegCpyIdx. + {&PartMappings[0], 1}, {&PartMappings[2], 1}, + // 23: GPR 64-bit value to FPR 64-bit value. + {&PartMappings[1], 1}, {&PartMappings[3], 1}, + // 25: FPR 32-bit value to GPR 32-bit value. + {&PartMappings[2], 1}, {&PartMappings[0], 1}, + // 27: FPR 64-bit value to GPR 64-bit value. <-- This must match LastCrossRegCpyIdx. + {&PartMappings[3], 1}, {&PartMappings[1], 1} + }; /// Get the pointer to the ValueMapping representing the RegisterBank @@ -112,5 +125,28 @@ getValueMapping(PartialMappingIdx RBIdx, unsigned Size) { 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 ? FirstGPR : FirstFPR; + PartialMappingIdx SrcRBIdx = SrcIsGPR ? FirstGPR : FirstFPR; + if (DstRBIdx == SrcRBIdx) + return getValueMapping(DstRBIdx, Size); + assert(Size <= 64 && "GPR cannot handle that size"); + unsigned ValMappingIdx = + FirstCrossRegCpyIdx + + (DstRBIdx - FirstGPR + getRegBankBaseIdxOffset(Size)) * + ValueMappingIdx::DistanceBetweenCrossRegCpy; + assert(ValMappingIdx >= AArch64::FirstCrossRegCpyIdx && + ValMappingIdx <= AArch64::LastCrossRegCpyIdx && + "Mapping out of bound"); + return &ValMappings[ValMappingIdx]; +} + } // End AArch64 namespace. } // End llvm namespace. diff --git a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index 35d62c46909..71a1bbee046 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -170,6 +170,36 @@ AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI) CHECK_VALUEMAP_3OPS(FPR, 256); CHECK_VALUEMAP_3OPS(FPR, 512); +#define CHECK_VALUEMAP_CROSSREGCPY(RBNameDst, RBNameSrc, Size) \ + do { \ + AArch64::PartialMappingIdx PartialMapDstIdx = \ + AArch64::PartialMappingIdx::RBNameDst##Size; \ + AArch64::PartialMappingIdx PartialMapSrcIdx = \ + AArch64::PartialMappingIdx::RBNameSrc##Size; \ + (void) PartialMapDstIdx; \ + (void) PartialMapSrcIdx; \ + const ValueMapping *Map = AArch64::getCopyMapping( \ + AArch64::First##RBNameDst == AArch64::FirstGPR, \ + AArch64::First##RBNameSrc == AArch64::FirstGPR, Size); \ + (void) Map; \ + assert(Map[0].BreakDown == &AArch64::PartMappings[PartialMapDstIdx] && \ + Map[0].NumBreakDowns == 1 && #RBNameDst #Size \ + " Dst is incorrectly initialized"); \ + assert(Map[1].BreakDown == &AArch64::PartMappings[PartialMapSrcIdx] && \ + Map[1].NumBreakDowns == 1 && #RBNameSrc #Size \ + " Src is incorrectly initialized"); \ + \ + } while (0) + + CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 32); + CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 32); + CHECK_VALUEMAP_CROSSREGCPY(GPR, GPR, 64); + CHECK_VALUEMAP_CROSSREGCPY(GPR, FPR, 64); + CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 32); + CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 32); + CHECK_VALUEMAP_CROSSREGCPY(FPR, FPR, 64); + CHECK_VALUEMAP_CROSSREGCPY(FPR, GPR, 64); + assert(verify(TRI) && "Invalid register bank information"); } |

