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