AArch64GenRegisterBankInfo.def 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. /// \file
  9. /// This file defines all the static objects used by AArch64RegisterBankInfo.
  10. /// \todo This should be generated by TableGen.
  11. //===----------------------------------------------------------------------===//
  12. namespace llvm {
  13. RegisterBankInfo::PartialMapping AArch64GenRegisterBankInfo::PartMappings[]{
  14. /* StartIdx, Length, RegBank */
  15. // 0: FPR 16-bit value.
  16. {0, 16, AArch64::FPRRegBank},
  17. // 1: FPR 32-bit value.
  18. {0, 32, AArch64::FPRRegBank},
  19. // 2: FPR 64-bit value.
  20. {0, 64, AArch64::FPRRegBank},
  21. // 3: FPR 128-bit value.
  22. {0, 128, AArch64::FPRRegBank},
  23. // 4: FPR 256-bit value.
  24. {0, 256, AArch64::FPRRegBank},
  25. // 5: FPR 512-bit value.
  26. {0, 512, AArch64::FPRRegBank},
  27. // 6: GPR 32-bit value.
  28. {0, 32, AArch64::GPRRegBank},
  29. // 7: GPR 64-bit value.
  30. {0, 64, AArch64::GPRRegBank},
  31. // 8: GPR 128-bit value.
  32. {0, 128, AArch64::GPRRegBank},
  33. };
  34. // ValueMappings.
  35. RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{
  36. /* BreakDown, NumBreakDowns */
  37. // 0: invalid
  38. {nullptr, 0},
  39. // 3-operands instructions (all binary operations should end up with one of
  40. // those mapping).
  41. // 1: FPR 16-bit value. <-- This must match First3OpsIdx.
  42. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1},
  43. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1},
  44. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1},
  45. // 4: FPR 32-bit value. <-- This must match First3OpsIdx.
  46. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
  47. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
  48. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
  49. // 7: FPR 64-bit value.
  50. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
  51. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
  52. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
  53. // 10: FPR 128-bit value.
  54. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
  55. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
  56. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
  57. // 13: FPR 256-bit value.
  58. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
  59. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
  60. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
  61. // 16: FPR 512-bit value.
  62. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
  63. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
  64. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
  65. // 19: GPR 32-bit value.
  66. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
  67. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
  68. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
  69. // 22: GPR 64-bit value.
  70. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
  71. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
  72. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
  73. // 25: GPR 128-bit value. <-- This must match Last3OpsIdx.
  74. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR128 - PMI_Min], 1},
  75. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR128 - PMI_Min], 1},
  76. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR128 - PMI_Min], 1},
  77. // Cross register bank copies.
  78. // 28: FPR 16-bit value to GPR 16-bit. <-- This must match
  79. // FirstCrossRegCpyIdx.
  80. // Note: This is the kind of copy we see with physical registers.
  81. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1},
  82. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
  83. // 30: FPR 32-bit value to GPR 32-bit value.
  84. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
  85. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
  86. // 32: FPR 64-bit value to GPR 64-bit value.
  87. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
  88. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
  89. // 34: FPR 128-bit value to GPR 128-bit value (invalid)
  90. {nullptr, 1},
  91. {nullptr, 1},
  92. // 36: FPR 256-bit value to GPR 256-bit value (invalid)
  93. {nullptr, 1},
  94. {nullptr, 1},
  95. // 38: FPR 512-bit value to GPR 512-bit value (invalid)
  96. {nullptr, 1},
  97. {nullptr, 1},
  98. // 40: GPR 32-bit value to FPR 32-bit value.
  99. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
  100. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
  101. // 42: GPR 64-bit value to FPR 64-bit value. <-- This must match
  102. // LastCrossRegCpyIdx.
  103. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
  104. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
  105. // 44: FPExt: 16 to 32. <-- This must match FPExt16To32Idx.
  106. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
  107. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1},
  108. // 46: FPExt: 16 to 32. <-- This must match FPExt16To64Idx.
  109. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
  110. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1},
  111. // 48: FPExt: 32 to 64. <-- This must match FPExt32To64Idx.
  112. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
  113. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
  114. // 50: FPExt vector: 64 to 128. <-- This must match FPExt64To128Idx.
  115. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
  116. {&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
  117. // 52: Shift scalar with 64 bit shift imm
  118. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
  119. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
  120. {&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
  121. };
  122. bool AArch64GenRegisterBankInfo::checkPartialMap(unsigned Idx,
  123. unsigned ValStartIdx,
  124. unsigned ValLength,
  125. const RegisterBank &RB) {
  126. const PartialMapping &Map = PartMappings[Idx - PartialMappingIdx::PMI_Min];
  127. return Map.StartIdx == ValStartIdx && Map.Length == ValLength &&
  128. Map.RegBank == &RB;
  129. }
  130. bool AArch64GenRegisterBankInfo::checkValueMapImpl(unsigned Idx,
  131. unsigned FirstInBank,
  132. unsigned Size,
  133. unsigned Offset) {
  134. unsigned PartialMapBaseIdx = Idx - PartialMappingIdx::PMI_Min;
  135. const ValueMapping &Map =
  136. AArch64GenRegisterBankInfo::getValueMapping((PartialMappingIdx)FirstInBank, Size)[Offset];
  137. return Map.BreakDown == &PartMappings[PartialMapBaseIdx] &&
  138. Map.NumBreakDowns == 1;
  139. }
  140. bool AArch64GenRegisterBankInfo::checkPartialMappingIdx(
  141. PartialMappingIdx FirstAlias, PartialMappingIdx LastAlias,
  142. ArrayRef<PartialMappingIdx> Order) {
  143. if (Order.front() != FirstAlias)
  144. return false;
  145. if (Order.back() != LastAlias)
  146. return false;
  147. if (Order.front() > Order.back())
  148. return false;
  149. PartialMappingIdx Previous = Order.front();
  150. bool First = true;
  151. for (const auto &Current : Order) {
  152. if (First) {
  153. First = false;
  154. continue;
  155. }
  156. if (Previous + 1 != Current)
  157. return false;
  158. Previous = Current;
  159. }
  160. return true;
  161. }
  162. unsigned AArch64GenRegisterBankInfo::getRegBankBaseIdxOffset(unsigned RBIdx,
  163. unsigned Size) {
  164. if (RBIdx == PMI_FirstGPR) {
  165. if (Size <= 32)
  166. return 0;
  167. if (Size <= 64)
  168. return 1;
  169. if (Size <= 128)
  170. return 2;
  171. return -1;
  172. }
  173. if (RBIdx == PMI_FirstFPR) {
  174. if (Size <= 16)
  175. return 0;
  176. if (Size <= 32)
  177. return 1;
  178. if (Size <= 64)
  179. return 2;
  180. if (Size <= 128)
  181. return 3;
  182. if (Size <= 256)
  183. return 4;
  184. if (Size <= 512)
  185. return 5;
  186. return -1;
  187. }
  188. return -1;
  189. }
  190. const RegisterBankInfo::ValueMapping *
  191. AArch64GenRegisterBankInfo::getValueMapping(PartialMappingIdx RBIdx,
  192. unsigned Size) {
  193. assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that");
  194. unsigned BaseIdxOffset = getRegBankBaseIdxOffset(RBIdx, Size);
  195. if (BaseIdxOffset == -1u)
  196. return &ValMappings[InvalidIdx];
  197. unsigned ValMappingIdx =
  198. First3OpsIdx + (RBIdx - PartialMappingIdx::PMI_Min + BaseIdxOffset) *
  199. ValueMappingIdx::DistanceBetweenRegBanks;
  200. assert(ValMappingIdx >= First3OpsIdx && ValMappingIdx <= Last3OpsIdx &&
  201. "Mapping out of bound");
  202. return &ValMappings[ValMappingIdx];
  203. }
  204. AArch64GenRegisterBankInfo::PartialMappingIdx
  205. AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{
  206. PMI_None, // CCR
  207. PMI_FirstFPR, // FPR
  208. PMI_FirstGPR, // GPR
  209. };
  210. const RegisterBankInfo::ValueMapping *
  211. AArch64GenRegisterBankInfo::getCopyMapping(unsigned DstBankID,
  212. unsigned SrcBankID, unsigned Size) {
  213. assert(DstBankID < AArch64::NumRegisterBanks && "Invalid bank ID");
  214. assert(SrcBankID < AArch64::NumRegisterBanks && "Invalid bank ID");
  215. PartialMappingIdx DstRBIdx = BankIDToCopyMapIdx[DstBankID];
  216. PartialMappingIdx SrcRBIdx = BankIDToCopyMapIdx[SrcBankID];
  217. assert(DstRBIdx != PMI_None && "No such mapping");
  218. assert(SrcRBIdx != PMI_None && "No such mapping");
  219. if (DstRBIdx == SrcRBIdx)
  220. return getValueMapping(DstRBIdx, Size);
  221. assert(Size <= 64 && "GPR cannot handle that size");
  222. unsigned ValMappingIdx =
  223. FirstCrossRegCpyIdx +
  224. (DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(DstRBIdx, Size)) *
  225. ValueMappingIdx::DistanceBetweenCrossRegCpy;
  226. assert(ValMappingIdx >= FirstCrossRegCpyIdx &&
  227. ValMappingIdx <= LastCrossRegCpyIdx && "Mapping out of bound");
  228. return &ValMappings[ValMappingIdx];
  229. }
  230. const RegisterBankInfo::ValueMapping *
  231. AArch64GenRegisterBankInfo::getFPExtMapping(unsigned DstSize,
  232. unsigned SrcSize) {
  233. // We support:
  234. // - For Scalar:
  235. // - 16 to 32.
  236. // - 16 to 64.
  237. // - 32 to 64.
  238. // => FPR 16 to FPR 32|64
  239. // => FPR 32 to FPR 64
  240. // - For vectors:
  241. // - v4f16 to v4f32
  242. // - v2f32 to v2f64
  243. // => FPR 64 to FPR 128
  244. // Check that we have been asked sensible sizes.
  245. if (SrcSize == 16) {
  246. assert((DstSize == 32 || DstSize == 64) && "Unexpected half extension");
  247. if (DstSize == 32)
  248. return &ValMappings[FPExt16To32Idx];
  249. return &ValMappings[FPExt16To64Idx];
  250. }
  251. if (SrcSize == 32) {
  252. assert(DstSize == 64 && "Unexpected float extension");
  253. return &ValMappings[FPExt32To64Idx];
  254. }
  255. assert((SrcSize == 64 || DstSize == 128) && "Unexpected vector extension");
  256. return &ValMappings[FPExt64To128Idx];
  257. }
  258. } // End llvm namespace.