xref: /llvm-project/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp (revision afa3afa384aa98b9a4557154fe0be42c62d6ae80)
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     return getRegBank(Mips::GPRBRegBankID);
83   case Mips::FGRCCRegClassID:
84   case Mips::FGR32RegClassID:
85   case Mips::FGR64RegClassID:
86   case Mips::AFGR64RegClassID:
87     return getRegBank(Mips::FPRBRegBankID);
88   default:
89     llvm_unreachable("Register class not supported");
90   }
91 }
92 
93 const RegisterBankInfo::InstructionMapping &
94 MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
95 
96   unsigned Opc = MI.getOpcode();
97   const MachineFunction &MF = *MI.getParent()->getParent();
98   const MachineRegisterInfo &MRI = MF.getRegInfo();
99 
100   const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
101   if (Mapping.isValid())
102     return Mapping;
103 
104   using namespace TargetOpcode;
105 
106   unsigned NumOperands = MI.getNumOperands();
107   const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
108 
109   switch (Opc) {
110   case G_TRUNC:
111   case G_ADD:
112   case G_SUB:
113   case G_MUL:
114   case G_UMULH:
115   case G_LOAD:
116   case G_STORE:
117   case G_ZEXTLOAD:
118   case G_SEXTLOAD:
119   case G_GEP:
120   case G_AND:
121   case G_OR:
122   case G_XOR:
123   case G_SHL:
124   case G_ASHR:
125   case G_LSHR:
126   case G_SDIV:
127   case G_UDIV:
128   case G_SREM:
129   case G_UREM:
130     OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
131     break;
132   case G_FADD:
133   case G_FSUB:
134   case G_FMUL:
135   case G_FDIV: {
136     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
137     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
138     OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
139                                  : &Mips::ValueMappings[Mips::DPRIdx];
140     break;
141   }
142   case G_FCONSTANT: {
143     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
144     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
145     const RegisterBankInfo::ValueMapping *FPRValueMapping =
146         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
147                    : &Mips::ValueMappings[Mips::DPRIdx];
148     OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr});
149     break;
150   }
151   case G_CONSTANT:
152   case G_FRAME_INDEX:
153   case G_GLOBAL_VALUE:
154   case G_BRCOND:
155     OperandsMapping =
156         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr});
157     break;
158   case G_ICMP:
159     OperandsMapping =
160         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
161                             &Mips::ValueMappings[Mips::GPRIdx],
162                             &Mips::ValueMappings[Mips::GPRIdx]});
163     break;
164   case G_SELECT:
165     OperandsMapping =
166         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
167                             &Mips::ValueMappings[Mips::GPRIdx],
168                             &Mips::ValueMappings[Mips::GPRIdx],
169                             &Mips::ValueMappings[Mips::GPRIdx]});
170     break;
171   default:
172     return getInvalidInstructionMapping();
173   }
174 
175   return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
176                                NumOperands);
177 }
178