aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/AArch64/AArch64GenRegisterBankInfo.def
blob: e927d58ad612bc7ccb185b1aacc2a10c1a9f2122 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//===- 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 {
  PMI_None = -1,
  PMI_GPR32 = 1,
  PMI_GPR64,
  PMI_FPR32,
  PMI_FPR64,
  PMI_FPR128,
  PMI_FPR256,
  PMI_FPR512,
  PMI_FirstGPR = PMI_GPR32,
  PMI_LastGPR = PMI_GPR64,
  PMI_FirstFPR = PMI_FPR32,
  PMI_LastFPR = PMI_FPR512,
  PMI_Min = PMI_FirstGPR,
};

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[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}
};

/// 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::PMI_None && "No mapping needed for that");
  unsigned ValMappingIdx = First3OpsIdx +
                           (RBIdx - AArch64::PartialMappingIdx::PMI_Min +
                            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 ? PMI_FirstGPR : PMI_FirstFPR;
  PartialMappingIdx SrcRBIdx = SrcIsGPR ? PMI_FirstGPR : PMI_FirstFPR;
  if (DstRBIdx == SrcRBIdx)
    return getValueMapping(DstRBIdx, Size);
  assert(Size <= 64 && "GPR cannot handle that size");
  unsigned ValMappingIdx =
      FirstCrossRegCpyIdx +
      (DstRBIdx - PMI_Min + getRegBankBaseIdxOffset(Size)) *
          ValueMappingIdx::DistanceBetweenCrossRegCpy;
  assert(ValMappingIdx >= AArch64::FirstCrossRegCpyIdx &&
         ValMappingIdx <= AArch64::LastCrossRegCpyIdx &&
         "Mapping out of bound");
  return &ValMappings[ValMappingIdx];
}

} // End AArch64 namespace.
} // End llvm namespace.