xref: /llvm-project/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp (revision 0a1fd355b2f6fb971fbf4108be623b01c65e57c4)
1 //===- MipsRegisterBankInfo.cpp ---------------------------------*- 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 implements the targeting of the RegisterBankInfo class for Mips.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12 
13 #include "MipsInstrInfo.h"
14 #include "MipsRegisterBankInfo.h"
15 #include "llvm/CodeGen/MachineRegisterInfo.h"
16 
17 #define GET_TARGET_REGBANK_IMPL
18 
19 #define DEBUG_TYPE "registerbankinfo"
20 
21 #include "MipsGenRegisterBank.inc"
22 
23 namespace llvm {
24 namespace Mips {
25 enum PartialMappingIdx {
26   PMI_GPR,
27   PMI_SPR,
28   PMI_DPR,
29   PMI_Min = PMI_GPR,
30 };
31 
32 RegisterBankInfo::PartialMapping PartMappings[]{
33     {0, 32, GPRBRegBank},
34     {0, 32, FPRBRegBank},
35     {0, 64, FPRBRegBank}
36 };
37 
38 enum ValueMappingIdx {
39     InvalidIdx = 0,
40     GPRIdx = 1,
41     SPRIdx = 4,
42     DPRIdx = 7
43 };
44 
45 RegisterBankInfo::ValueMapping ValueMappings[] = {
46     // invalid
47     {nullptr, 0},
48     // up to 3 operands in GPRs
49     {&PartMappings[PMI_GPR - PMI_Min], 1},
50     {&PartMappings[PMI_GPR - PMI_Min], 1},
51     {&PartMappings[PMI_GPR - PMI_Min], 1},
52     // up to 3 ops operands FPRs - single precission
53     {&PartMappings[PMI_SPR - PMI_Min], 1},
54     {&PartMappings[PMI_SPR - PMI_Min], 1},
55     {&PartMappings[PMI_SPR - PMI_Min], 1},
56     // up to 3 ops operands FPRs - double precission
57     {&PartMappings[PMI_DPR - PMI_Min], 1},
58     {&PartMappings[PMI_DPR - PMI_Min], 1},
59     {&PartMappings[PMI_DPR - PMI_Min], 1}
60 };
61 
62 } // end namespace Mips
63 } // end namespace llvm
64 
65 using namespace llvm;
66 
67 MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
68     : MipsGenRegisterBankInfo() {}
69 
70 const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass(
71     const TargetRegisterClass &RC) const {
72   using namespace Mips;
73 
74   switch (RC.getID()) {
75   case Mips::GPR32RegClassID:
76   case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
77   case Mips::GPRMM16MovePPairFirstRegClassID:
78   case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
79   case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
80   case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
81   case Mips::SP32RegClassID:
82   case Mips::GP32RegClassID:
83     return getRegBank(Mips::GPRBRegBankID);
84   case Mips::FGRCCRegClassID:
85   case Mips::FGR32RegClassID:
86   case Mips::FGR64RegClassID:
87   case Mips::AFGR64RegClassID:
88     return getRegBank(Mips::FPRBRegBankID);
89   default:
90     llvm_unreachable("Register class not supported");
91   }
92 }
93 
94 const RegisterBankInfo::InstructionMapping &
95 MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
96 
97   unsigned Opc = MI.getOpcode();
98   const MachineFunction &MF = *MI.getParent()->getParent();
99   const MachineRegisterInfo &MRI = MF.getRegInfo();
100 
101   const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
102   if (Mapping.isValid())
103     return Mapping;
104 
105   using namespace TargetOpcode;
106 
107   unsigned NumOperands = MI.getNumOperands();
108   const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
109 
110   switch (Opc) {
111   case G_TRUNC:
112   case G_ADD:
113   case G_SUB:
114   case G_MUL:
115   case G_UMULH:
116   case G_LOAD:
117   case G_STORE:
118   case G_ZEXTLOAD:
119   case G_SEXTLOAD:
120   case G_GEP:
121   case G_AND:
122   case G_OR:
123   case G_XOR:
124   case G_SHL:
125   case G_ASHR:
126   case G_LSHR:
127   case G_SDIV:
128   case G_UDIV:
129   case G_SREM:
130   case G_UREM:
131     OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
132     break;
133   case G_FADD:
134   case G_FSUB:
135   case G_FMUL:
136   case G_FDIV:
137   case G_FABS: {
138     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
139     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
140     OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
141                                  : &Mips::ValueMappings[Mips::DPRIdx];
142     break;
143   }
144   case G_FCONSTANT: {
145     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
146     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
147     const RegisterBankInfo::ValueMapping *FPRValueMapping =
148         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
149                    : &Mips::ValueMappings[Mips::DPRIdx];
150     OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr});
151     break;
152   }
153   case G_FCMP: {
154     unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
155     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
156     const RegisterBankInfo::ValueMapping *FPRValueMapping =
157         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
158                    : &Mips::ValueMappings[Mips::DPRIdx];
159     OperandsMapping =
160         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
161                             FPRValueMapping, FPRValueMapping});
162     break;
163   }
164   case G_FPEXT:
165     OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx],
166                                           &Mips::ValueMappings[Mips::SPRIdx]});
167     break;
168   case G_FPTRUNC:
169     OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx],
170                                           &Mips::ValueMappings[Mips::DPRIdx]});
171     break;
172   case G_CONSTANT:
173   case G_FRAME_INDEX:
174   case G_GLOBAL_VALUE:
175   case G_BRCOND:
176     OperandsMapping =
177         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr});
178     break;
179   case G_ICMP:
180     OperandsMapping =
181         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
182                             &Mips::ValueMappings[Mips::GPRIdx],
183                             &Mips::ValueMappings[Mips::GPRIdx]});
184     break;
185   case G_SELECT:
186     OperandsMapping =
187         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
188                             &Mips::ValueMappings[Mips::GPRIdx],
189                             &Mips::ValueMappings[Mips::GPRIdx],
190                             &Mips::ValueMappings[Mips::GPRIdx]});
191     break;
192   default:
193     return getInvalidInstructionMapping();
194   }
195 
196   return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
197                                NumOperands);
198 }
199