]> granicus.if.org Git - llvm/commitdiff
[AArch64][RegisterBankInfo] Describe cross regbank copies statically.
authorQuentin Colombet <qcolombet@apple.com>
Thu, 13 Oct 2016 00:12:06 +0000 (00:12 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Thu, 13 Oct 2016 00:12:06 +0000 (00:12 +0000)
NFC.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284091 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64GenRegisterBankInfo.def
lib/Target/AArch64/AArch64RegisterBankInfo.cpp

index 88dac21bab34da9ef1ec5ab453414489d76f59a4..621bd14cc5f84c91926d0d2594b5672fe64ab2d3 100644 (file)
@@ -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.
index 35d62c46909e984d6fd6bf2008a2ac5742fbba0d..71a1bbee046555d135b9e9b01a3d22b481075deb 100644 (file)
@@ -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");
 }