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