blob: 37720cbd32bbbc5d6404d027fd6423238bb9bdf4 [file] [log] [blame]
//===- 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. <-- This must match
// FirstCrossRegCpyIdx.
// Note: This is the kind of copy we see with physical registers.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR16 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 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<PartialMappingIdx> 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.