xref: /llvm-project/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp (revision 22e99c434fb65ca8a9d5e3dbf5db5965681ce5c3)
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     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
138     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
139     OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
140                                  : &Mips::ValueMappings[Mips::DPRIdx];
141     break;
142   }
143   case G_FCONSTANT: {
144     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
145     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
146     const RegisterBankInfo::ValueMapping *FPRValueMapping =
147         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
148                    : &Mips::ValueMappings[Mips::DPRIdx];
149     OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr});
150     break;
151   }
152   case G_FCMP: {
153     unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
154     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
155     const RegisterBankInfo::ValueMapping *FPRValueMapping =
156         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
157                    : &Mips::ValueMappings[Mips::DPRIdx];
158     OperandsMapping =
159         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
160                             FPRValueMapping, FPRValueMapping});
161     break;
162   }
163   case G_CONSTANT:
164   case G_FRAME_INDEX:
165   case G_GLOBAL_VALUE:
166   case G_BRCOND:
167     OperandsMapping =
168         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr});
169     break;
170   case G_ICMP:
171     OperandsMapping =
172         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
173                             &Mips::ValueMappings[Mips::GPRIdx],
174                             &Mips::ValueMappings[Mips::GPRIdx]});
175     break;
176   case G_SELECT:
177     OperandsMapping =
178         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
179                             &Mips::ValueMappings[Mips::GPRIdx],
180                             &Mips::ValueMappings[Mips::GPRIdx],
181                             &Mips::ValueMappings[Mips::GPRIdx]});
182     break;
183   default:
184     return getInvalidInstructionMapping();
185   }
186 
187   return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
188                                NumOperands);
189 }
190