xref: /llvm-project/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp (revision 153bd24eda1f4f471d9e2eebad195ed49668c6a8)
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   case G_FSQRT:{
139     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
140     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
141     OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
142                                  : &Mips::ValueMappings[Mips::DPRIdx];
143     break;
144   }
145   case G_FCONSTANT: {
146     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
147     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
148     const RegisterBankInfo::ValueMapping *FPRValueMapping =
149         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
150                    : &Mips::ValueMappings[Mips::DPRIdx];
151     OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr});
152     break;
153   }
154   case G_FCMP: {
155     unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
156     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
157     const RegisterBankInfo::ValueMapping *FPRValueMapping =
158         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
159                    : &Mips::ValueMappings[Mips::DPRIdx];
160     OperandsMapping =
161         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
162                             FPRValueMapping, FPRValueMapping});
163     break;
164   }
165   case G_FPEXT:
166     OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx],
167                                           &Mips::ValueMappings[Mips::SPRIdx]});
168     break;
169   case G_FPTRUNC:
170     OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx],
171                                           &Mips::ValueMappings[Mips::DPRIdx]});
172     break;
173   case G_FPTOSI: {
174     unsigned SizeInt = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
175     unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
176     assert((SizeInt == 32) && "Unsupported integer size");
177     assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size");
178     OperandsMapping = getOperandsMapping({
179         &Mips::ValueMappings[Mips::GPRIdx],
180         SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
181                      : &Mips::ValueMappings[Mips::DPRIdx],
182     });
183     break;
184   }
185   case G_SITOFP: {
186     unsigned SizeInt = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
187     unsigned SizeFP = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
188     assert((SizeInt == 32) && "Unsupported integer size");
189     assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size");
190     OperandsMapping =
191         getOperandsMapping({SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
192                                          : &Mips::ValueMappings[Mips::DPRIdx],
193                             &Mips::ValueMappings[Mips::GPRIdx]});
194     break;
195   }
196   case G_CONSTANT:
197   case G_FRAME_INDEX:
198   case G_GLOBAL_VALUE:
199   case G_BRCOND:
200     OperandsMapping =
201         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr});
202     break;
203   case G_ICMP:
204     OperandsMapping =
205         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
206                             &Mips::ValueMappings[Mips::GPRIdx],
207                             &Mips::ValueMappings[Mips::GPRIdx]});
208     break;
209   case G_SELECT:
210     OperandsMapping =
211         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
212                             &Mips::ValueMappings[Mips::GPRIdx],
213                             &Mips::ValueMappings[Mips::GPRIdx],
214                             &Mips::ValueMappings[Mips::GPRIdx]});
215     break;
216   default:
217     return getInvalidInstructionMapping();
218   }
219 
220   return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
221                                NumOperands);
222 }
223