1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00
llvm-mirror/lib/Target/AArch64/AArch64GenRegisterBankInfo.def
2016-10-13 00:12:06 +00:00

153 lines
5.1 KiB
C++

//===- 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};
// PartialMappings.
enum PartialMappingIdx {
None = -1,
GPR32 = 0,
GPR64,
FPR32,
FPR64,
FPR128,
FPR256,
FPR512,
FirstGPR = GPR32,
LastGPR = GPR64,
FirstFPR = FPR32,
LastFPR = FPR512
};
static unsigned getRegBankBaseIdxOffset(unsigned Size) {
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},
// 4: FPR 128-bit value.
{0, 128, FPRRegBank},
// 5: FPR 256-bit value.
{0, 256, FPRRegBank},
// 6: FPR 512-bit value.
{0, 512, FPRRegBank}
};
enum ValueMappingIdx {
First3OpsIdx = 0,
Last3OpsIdx = 18,
DistanceBetweenRegBanks = 3,
FirstCrossRegCpyIdx = 21,
LastCrossRegCpyIdx = 27,
DistanceBetweenCrossRegCpy = 2
};
// ValueMappings.
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[0], 1}, {&PartMappings[0], 1}, {&PartMappings[0], 1},
// 3: GPR 64-bit value.
{&PartMappings[1], 1}, {&PartMappings[1], 1}, {&PartMappings[1], 1},
// 6: FPR 32-bit value.
{&PartMappings[2], 1}, {&PartMappings[2], 1}, {&PartMappings[2], 1},
// 9: FPR 64-bit value.
{&PartMappings[3], 1}, {&PartMappings[3], 1}, {&PartMappings[3], 1},
// 12: FPR 128-bit value.
{&PartMappings[4], 1}, {&PartMappings[4], 1}, {&PartMappings[4], 1},
// 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},
// 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
/// at \p RBIdx with a size of \p Size.
///
/// The returned mapping works for instructions with the same kind of
/// operands for up to 3 operands.
///
/// \pre \p RBIdx != PartialMappingIdx::None
const RegisterBankInfo::ValueMapping *
getValueMapping(PartialMappingIdx RBIdx, unsigned Size) {
assert(RBIdx != PartialMappingIdx::None && "No mapping needed for that");
unsigned ValMappingIdx = First3OpsIdx +
(RBIdx + getRegBankBaseIdxOffset(Size)) *
ValueMappingIdx::DistanceBetweenRegBanks;
assert(ValMappingIdx >= AArch64::First3OpsIdx &&
ValMappingIdx <= AArch64::Last3OpsIdx && "Mapping out of bound");
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.