1//===- AArch64RegisterBankInfo -----------------------------------*- 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 declares the targeting of the RegisterBankInfo class for AArch64.
10/// \todo This should be generated by TableGen.
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64REGISTERBANKINFO_H
14#define LLVM_LIB_TARGET_AARCH64_AARCH64REGISTERBANKINFO_H
15
16#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
17#include "llvm/CodeGen/RegisterBankInfo.h"
18
19#define GET_REGBANK_DECLARATIONS
20#include "AArch64GenRegisterBank.inc"
21
22namespace llvm {
23
24class TargetRegisterInfo;
25class AArch64RegisterInfo;
26
27class AArch64GenRegisterBankInfo : public RegisterBankInfo {
28protected:
29 enum PartialMappingIdx {
30 PMI_None = -1,
31 PMI_FPR16 = 1,
32 PMI_FPR32,
33 PMI_FPR64,
34 PMI_FPR128,
35 PMI_FPR256,
36 PMI_FPR512,
37 PMI_GPR32,
38 PMI_GPR64,
39 PMI_GPR128,
40 PMI_FirstGPR = PMI_GPR32,
41 PMI_LastGPR = PMI_GPR128,
42 PMI_FirstFPR = PMI_FPR16,
43 PMI_LastFPR = PMI_FPR512,
44 PMI_Min = PMI_FirstFPR,
45 };
46
47 static const RegisterBankInfo::PartialMapping PartMappings[];
48 static const RegisterBankInfo::ValueMapping ValMappings[];
49 static const PartialMappingIdx BankIDToCopyMapIdx[];
50
51 enum ValueMappingIdx {
52 InvalidIdx = 0,
53 First3OpsIdx = 1,
54 Last3OpsIdx = 25,
55 DistanceBetweenRegBanks = 3,
56 FirstCrossRegCpyIdx = 28,
57 LastCrossRegCpyIdx = 42,
58 DistanceBetweenCrossRegCpy = 2,
59 FPExt16To32Idx = 44,
60 FPExt16To64Idx = 46,
61 FPExt32To64Idx = 48,
62 FPExt64To128Idx = 50,
63 Shift64Imm = 52,
64 };
65
66 static bool checkPartialMap(unsigned Idx, unsigned ValStartIdx,
67 unsigned ValLength, const RegisterBank &RB);
68 static bool checkValueMapImpl(unsigned Idx, unsigned FirstInBank,
69 unsigned Size, unsigned Offset);
70 static bool checkPartialMappingIdx(PartialMappingIdx FirstAlias,
71 PartialMappingIdx LastAlias,
72 ArrayRef<PartialMappingIdx> Order);
73
74 static unsigned getRegBankBaseIdxOffset(unsigned RBIdx, TypeSize Size);
75
76 /// Get the pointer to the ValueMapping representing the RegisterBank
77 /// at \p RBIdx with a size of \p Size.
78 ///
79 /// The returned mapping works for instructions with the same kind of
80 /// operands for up to 3 operands.
81 ///
82 /// \pre \p RBIdx != PartialMappingIdx::None
83 static const RegisterBankInfo::ValueMapping *
84 getValueMapping(PartialMappingIdx RBIdx, TypeSize Size);
85
86 /// Get the pointer to the ValueMapping of the operands of a copy
87 /// instruction from the \p SrcBankID register bank to the \p DstBankID
88 /// register bank with a size of \p Size.
89 static const RegisterBankInfo::ValueMapping *
90 getCopyMapping(unsigned DstBankID, unsigned SrcBankID, TypeSize Size);
91
92 /// Get the instruction mapping for G_FPEXT.
93 ///
94 /// \pre (DstSize, SrcSize) pair is one of the following:
95 /// (32, 16), (64, 16), (64, 32), (128, 64)
96 ///
97 /// \return An InstructionMapping with statically allocated OperandsMapping.
98 static const RegisterBankInfo::ValueMapping *
99 getFPExtMapping(unsigned DstSize, unsigned SrcSize);
100
101#define GET_TARGET_REGBANK_CLASS
102#include "AArch64GenRegisterBank.inc"
103};
104
105/// This class provides the information for the target register banks.
106class AArch64RegisterBankInfo final : public AArch64GenRegisterBankInfo {
107 /// See RegisterBankInfo::applyMapping.
108 void applyMappingImpl(MachineIRBuilder &Builder,
109 const OperandsMapper &OpdMapper) const override;
110
111 /// Get an instruction mapping where all the operands map to
112 /// the same register bank and have similar size.
113 ///
114 /// \pre MI.getNumOperands() <= 3
115 ///
116 /// \return An InstructionMappings with a statically allocated
117 /// OperandsMapping.
118 const InstructionMapping &
119 getSameKindOfOperandsMapping(const MachineInstr &MI) const;
120
121 /// Maximum recursion depth for hasFPConstraints.
122 const unsigned MaxFPRSearchDepth = 2;
123
124 /// \returns true if \p MI is a PHI that its def is used by
125 /// any instruction that onlyUsesFP.
126 bool isPHIWithFPConstraints(const MachineInstr &MI,
127 const MachineRegisterInfo &MRI,
128 const AArch64RegisterInfo &TRI,
129 unsigned Depth = 0) const;
130
131 /// \returns true if \p MI only uses and defines FPRs.
132 bool hasFPConstraints(const MachineInstr &MI, const MachineRegisterInfo &MRI,
133 const AArch64RegisterInfo &TRI,
134 unsigned Depth = 0) const;
135
136 /// \returns true if \p MI only uses FPRs.
137 bool onlyUsesFP(const MachineInstr &MI, const MachineRegisterInfo &MRI,
138 const AArch64RegisterInfo &TRI, unsigned Depth = 0) const;
139
140 /// \returns true if \p MI only defines FPRs.
141 bool onlyDefinesFP(const MachineInstr &MI, const MachineRegisterInfo &MRI,
142 const AArch64RegisterInfo &TRI, unsigned Depth = 0) const;
143
144 /// \returns true if \p MI can take both fpr and gpr uses, but prefers fp.
145 bool prefersFPUse(const MachineInstr &MI, const MachineRegisterInfo &MRI,
146 const AArch64RegisterInfo &TRI, unsigned Depth = 0) const;
147
148 /// \returns true if the load \p MI is likely loading from a floating-point
149 /// type.
150 bool isLoadFromFPType(const MachineInstr &MI) const;
151
152public:
153 AArch64RegisterBankInfo(const TargetRegisterInfo &TRI);
154
155 unsigned copyCost(const RegisterBank &A, const RegisterBank &B,
156 TypeSize Size) const override;
157
158 const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC,
159 LLT Ty) const override;
160
161 InstructionMappings
162 getInstrAlternativeMappings(const MachineInstr &MI) const override;
163
164 const InstructionMapping &
165 getInstrMapping(const MachineInstr &MI) const override;
166};
167} // End llvm namespace.
168#endif
169