2016-09-22 04:10:37 +02:00
|
|
|
//===- 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 {
|
|
|
|
|
|
|
|
RegisterBank GPRRegBank;
|
|
|
|
RegisterBank FPRRegBank;
|
|
|
|
RegisterBank CCRRegBank;
|
|
|
|
|
|
|
|
RegisterBank *RegBanks[] = {&GPRRegBank, &FPRRegBank, &CCRRegBank};
|
|
|
|
|
2016-09-23 02:14:36 +02:00
|
|
|
// PartialMappings.
|
|
|
|
enum PartialMappingIdx {
|
2016-12-06 12:33:04 +01:00
|
|
|
PMI_None = -1,
|
2016-12-06 15:39:57 +01:00
|
|
|
PMI_GPR32 = 1,
|
2016-12-06 12:33:04 +01:00
|
|
|
PMI_GPR64,
|
|
|
|
PMI_FPR32,
|
|
|
|
PMI_FPR64,
|
|
|
|
PMI_FPR128,
|
|
|
|
PMI_FPR256,
|
|
|
|
PMI_FPR512,
|
|
|
|
PMI_FirstGPR = PMI_GPR32,
|
|
|
|
PMI_LastGPR = PMI_GPR64,
|
|
|
|
PMI_FirstFPR = PMI_FPR32,
|
2016-12-06 14:55:01 +01:00
|
|
|
PMI_LastFPR = PMI_FPR512,
|
|
|
|
PMI_Min = PMI_FirstGPR,
|
2016-09-23 02:14:36 +02:00
|
|
|
};
|
|
|
|
|
2016-09-30 23:46:12 +02:00
|
|
|
static unsigned getRegBankBaseIdxOffset(unsigned Size) {
|
2016-09-23 02:14:36 +02:00
|
|
|
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},
|
2016-09-28 00:54:57 +02:00
|
|
|
// 4: FPR 128-bit value.
|
2016-09-23 02:14:36 +02:00
|
|
|
{0, 128, FPRRegBank},
|
2016-09-28 00:54:57 +02:00
|
|
|
// 5: FPR 256-bit value.
|
2016-09-23 02:14:36 +02:00
|
|
|
{0, 256, FPRRegBank},
|
2016-09-28 00:54:57 +02:00
|
|
|
// 6: FPR 512-bit value.
|
2016-09-23 02:14:36 +02:00
|
|
|
{0, 512, FPRRegBank}
|
|
|
|
};
|
|
|
|
|
2016-09-30 02:09:58 +02:00
|
|
|
enum ValueMappingIdx {
|
2016-09-30 23:46:17 +02:00
|
|
|
First3OpsIdx = 0,
|
|
|
|
Last3OpsIdx = 18,
|
2016-10-13 02:12:06 +02:00
|
|
|
DistanceBetweenRegBanks = 3,
|
|
|
|
FirstCrossRegCpyIdx = 21,
|
|
|
|
LastCrossRegCpyIdx = 27,
|
|
|
|
DistanceBetweenCrossRegCpy = 2
|
2016-09-30 02:09:58 +02:00
|
|
|
};
|
|
|
|
|
2016-09-28 00:55:04 +02:00
|
|
|
// ValueMappings.
|
2016-12-06 14:55:01 +01:00
|
|
|
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}
|
2016-09-28 00:55:04 +02:00
|
|
|
};
|
|
|
|
|
2016-09-30 23:46:15 +02:00
|
|
|
/// Get the pointer to the ValueMapping representing the RegisterBank
|
|
|
|
/// at \p RBIdx with a size of \p Size.
|
2016-09-30 23:46:17 +02:00
|
|
|
///
|
|
|
|
/// The returned mapping works for instructions with the same kind of
|
|
|
|
/// operands for up to 3 operands.
|
|
|
|
///
|
2016-09-30 23:46:15 +02:00
|
|
|
/// \pre \p RBIdx != PartialMappingIdx::None
|
2016-09-30 23:46:17 +02:00
|
|
|
const RegisterBankInfo::ValueMapping *
|
2016-09-30 23:46:19 +02:00
|
|
|
getValueMapping(PartialMappingIdx RBIdx, unsigned Size) {
|
2016-12-06 12:33:04 +01:00
|
|
|
assert(RBIdx != PartialMappingIdx::PMI_None && "No mapping needed for that");
|
2016-09-30 23:46:17 +02:00
|
|
|
unsigned ValMappingIdx = First3OpsIdx +
|
2016-12-06 15:39:57 +01:00
|
|
|
(RBIdx - AArch64::PartialMappingIdx::PMI_Min +
|
|
|
|
getRegBankBaseIdxOffset(Size)) *
|
|
|
|
ValueMappingIdx::DistanceBetweenRegBanks;
|
|
|
|
assert(ValMappingIdx >= AArch64::First3OpsIdx &&
|
|
|
|
ValMappingIdx <= AArch64::Last3OpsIdx && "Mapping out of bound");
|
2016-09-30 23:46:17 +02:00
|
|
|
|
|
|
|
return &ValMappings[ValMappingIdx];
|
2016-09-30 23:46:15 +02:00
|
|
|
}
|
|
|
|
|
2016-10-13 02:12:06 +02:00
|
|
|
/// 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) {
|
2016-12-06 12:33:04 +01:00
|
|
|
PartialMappingIdx DstRBIdx = DstIsGPR ? PMI_FirstGPR : PMI_FirstFPR;
|
|
|
|
PartialMappingIdx SrcRBIdx = SrcIsGPR ? PMI_FirstGPR : PMI_FirstFPR;
|
2016-10-13 02:12:06 +02:00
|
|
|
if (DstRBIdx == SrcRBIdx)
|
|
|
|
return getValueMapping(DstRBIdx, Size);
|
|
|
|
assert(Size <= 64 && "GPR cannot handle that size");
|
|
|
|
unsigned ValMappingIdx =
|
|
|
|
FirstCrossRegCpyIdx +
|
2016-12-06 15:39:57 +01:00
|
|
|
(DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(Size)) *
|
2016-10-13 02:12:06 +02:00
|
|
|
ValueMappingIdx::DistanceBetweenCrossRegCpy;
|
|
|
|
assert(ValMappingIdx >= AArch64::FirstCrossRegCpyIdx &&
|
|
|
|
ValMappingIdx <= AArch64::LastCrossRegCpyIdx &&
|
|
|
|
"Mapping out of bound");
|
|
|
|
return &ValMappings[ValMappingIdx];
|
|
|
|
}
|
|
|
|
|
2016-09-22 04:10:37 +02:00
|
|
|
} // End AArch64 namespace.
|
|
|
|
} // End llvm namespace.
|