1fac93e28SPetar Jovanovic //===- MipsRegisterBankInfo.cpp ---------------------------------*- C++ -*-===//
2fac93e28SPetar Jovanovic //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fac93e28SPetar Jovanovic //
7fac93e28SPetar Jovanovic //===----------------------------------------------------------------------===//
8fac93e28SPetar Jovanovic /// \file
9fac93e28SPetar Jovanovic /// This file implements the targeting of the RegisterBankInfo class for Mips.
10fac93e28SPetar Jovanovic /// \todo This should be generated by TableGen.
11fac93e28SPetar Jovanovic //===----------------------------------------------------------------------===//
12fac93e28SPetar Jovanovic 
13366857a2SPetar Jovanovic #include "MipsInstrInfo.h"
14fac93e28SPetar Jovanovic #include "MipsRegisterBankInfo.h"
15fac93e28SPetar Jovanovic #include "llvm/CodeGen/MachineRegisterInfo.h"
16fac93e28SPetar Jovanovic 
17366857a2SPetar Jovanovic #define GET_TARGET_REGBANK_IMPL
18fac93e28SPetar Jovanovic 
19366857a2SPetar Jovanovic #define DEBUG_TYPE "registerbankinfo"
20366857a2SPetar Jovanovic 
21366857a2SPetar Jovanovic #include "MipsGenRegisterBank.inc"
22366857a2SPetar Jovanovic 
23366857a2SPetar Jovanovic namespace llvm {
24366857a2SPetar Jovanovic namespace Mips {
25366857a2SPetar Jovanovic enum PartialMappingIdx {
26366857a2SPetar Jovanovic   PMI_GPR,
27*1af05df3SPetar Avramovic   PMI_SPR,
28*1af05df3SPetar Avramovic   PMI_DPR,
29366857a2SPetar Jovanovic   PMI_Min = PMI_GPR,
30366857a2SPetar Jovanovic };
31366857a2SPetar Jovanovic 
32366857a2SPetar Jovanovic RegisterBankInfo::PartialMapping PartMappings[]{
33*1af05df3SPetar Avramovic     {0, 32, GPRBRegBank},
34*1af05df3SPetar Avramovic     {0, 32, FPRBRegBank},
35*1af05df3SPetar Avramovic     {0, 64, FPRBRegBank}
36366857a2SPetar Jovanovic };
37366857a2SPetar Jovanovic 
38*1af05df3SPetar Avramovic enum ValueMappingIdx {
39*1af05df3SPetar Avramovic     InvalidIdx = 0,
40*1af05df3SPetar Avramovic     GPRIdx = 1,
41*1af05df3SPetar Avramovic     SPRIdx = 4,
42*1af05df3SPetar Avramovic     DPRIdx = 7
43*1af05df3SPetar Avramovic };
44366857a2SPetar Jovanovic 
45366857a2SPetar Jovanovic RegisterBankInfo::ValueMapping ValueMappings[] = {
46366857a2SPetar Jovanovic     // invalid
47366857a2SPetar Jovanovic     {nullptr, 0},
48*1af05df3SPetar Avramovic     // up to 3 operands in GPRs
49366857a2SPetar Jovanovic     {&PartMappings[PMI_GPR - PMI_Min], 1},
50366857a2SPetar Jovanovic     {&PartMappings[PMI_GPR - PMI_Min], 1},
51*1af05df3SPetar Avramovic     {&PartMappings[PMI_GPR - PMI_Min], 1},
52*1af05df3SPetar Avramovic     // up to 3 ops operands FPRs - single precission
53*1af05df3SPetar Avramovic     {&PartMappings[PMI_SPR - PMI_Min], 1},
54*1af05df3SPetar Avramovic     {&PartMappings[PMI_SPR - PMI_Min], 1},
55*1af05df3SPetar Avramovic     {&PartMappings[PMI_SPR - PMI_Min], 1},
56*1af05df3SPetar Avramovic     // up to 3 ops operands FPRs - double precission
57*1af05df3SPetar Avramovic     {&PartMappings[PMI_DPR - PMI_Min], 1},
58*1af05df3SPetar Avramovic     {&PartMappings[PMI_DPR - PMI_Min], 1},
59*1af05df3SPetar Avramovic     {&PartMappings[PMI_DPR - PMI_Min], 1}
60*1af05df3SPetar Avramovic };
61366857a2SPetar Jovanovic 
62366857a2SPetar Jovanovic } // end namespace Mips
63366857a2SPetar Jovanovic } // end namespace llvm
64366857a2SPetar Jovanovic 
65366857a2SPetar Jovanovic using namespace llvm;
66fac93e28SPetar Jovanovic 
67fac93e28SPetar Jovanovic MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI)
68fac93e28SPetar Jovanovic     : MipsGenRegisterBankInfo() {}
69366857a2SPetar Jovanovic 
70366857a2SPetar Jovanovic const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass(
71366857a2SPetar Jovanovic     const TargetRegisterClass &RC) const {
72366857a2SPetar Jovanovic   using namespace Mips;
73366857a2SPetar Jovanovic 
74366857a2SPetar Jovanovic   switch (RC.getID()) {
75366857a2SPetar Jovanovic   case Mips::GPR32RegClassID:
76366857a2SPetar Jovanovic   case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID:
77852dd83bSSimon Atanasyan   case Mips::GPRMM16MovePPairFirstRegClassID:
78852dd83bSSimon Atanasyan   case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID:
79366857a2SPetar Jovanovic   case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID:
80852dd83bSSimon Atanasyan   case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID:
81021e4c82SPetar Jovanovic   case Mips::SP32RegClassID:
82366857a2SPetar Jovanovic     return getRegBank(Mips::GPRBRegBankID);
833dfa368dSPetar Avramovic   case Mips::FGRCCRegClassID:
843dfa368dSPetar Avramovic   case Mips::FGR64RegClassID:
853dfa368dSPetar Avramovic   case Mips::AFGR64RegClassID:
863dfa368dSPetar Avramovic   case Mips::AFGR64_and_OddSPRegClassID:
873dfa368dSPetar Avramovic     return getRegBank(Mips::FPRBRegBankID);
88366857a2SPetar Jovanovic   default:
89366857a2SPetar Jovanovic     llvm_unreachable("Register class not supported");
90366857a2SPetar Jovanovic   }
91366857a2SPetar Jovanovic }
92366857a2SPetar Jovanovic 
93366857a2SPetar Jovanovic const RegisterBankInfo::InstructionMapping &
94366857a2SPetar Jovanovic MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
95366857a2SPetar Jovanovic 
96366857a2SPetar Jovanovic   unsigned Opc = MI.getOpcode();
97*1af05df3SPetar Avramovic   const MachineFunction &MF = *MI.getParent()->getParent();
98*1af05df3SPetar Avramovic   const MachineRegisterInfo &MRI = MF.getRegInfo();
99366857a2SPetar Jovanovic 
100366857a2SPetar Jovanovic   const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
101366857a2SPetar Jovanovic   if (Mapping.isValid())
102366857a2SPetar Jovanovic     return Mapping;
103366857a2SPetar Jovanovic 
104366857a2SPetar Jovanovic   using namespace TargetOpcode;
105366857a2SPetar Jovanovic 
106366857a2SPetar Jovanovic   unsigned NumOperands = MI.getNumOperands();
107366857a2SPetar Jovanovic   const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
108366857a2SPetar Jovanovic 
109366857a2SPetar Jovanovic   switch (Opc) {
1107cecadb9SPetar Avramovic   case G_TRUNC:
111366857a2SPetar Jovanovic   case G_ADD:
1127cecadb9SPetar Avramovic   case G_SUB:
11356dc218dSPetar Avramovic   case G_MUL:
114a48285a1SPetar Avramovic   case G_UMULH:
115021e4c82SPetar Jovanovic   case G_LOAD:
116021e4c82SPetar Jovanovic   case G_STORE:
11779df8596SPetar Avramovic   case G_ZEXTLOAD:
11879df8596SPetar Avramovic   case G_SEXTLOAD:
119021e4c82SPetar Jovanovic   case G_GEP:
1203b953c37SPetar Jovanovic   case G_AND:
1213b953c37SPetar Jovanovic   case G_OR:
1223b953c37SPetar Jovanovic   case G_XOR:
1233b953c37SPetar Jovanovic   case G_SHL:
1243b953c37SPetar Jovanovic   case G_ASHR:
1253b953c37SPetar Jovanovic   case G_LSHR:
1260a5e4eb7SPetar Avramovic   case G_SDIV:
1270a5e4eb7SPetar Avramovic   case G_UDIV:
1280a5e4eb7SPetar Avramovic   case G_SREM:
1290a5e4eb7SPetar Avramovic   case G_UREM:
130366857a2SPetar Jovanovic     OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
131366857a2SPetar Jovanovic     break;
132*1af05df3SPetar Avramovic   case G_FCONSTANT: {
133*1af05df3SPetar Avramovic     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
134*1af05df3SPetar Avramovic     unsigned Size = Ty.getSizeInBits();
135*1af05df3SPetar Avramovic     const RegisterBankInfo::ValueMapping *FPRValueMapping =
136*1af05df3SPetar Avramovic         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
137*1af05df3SPetar Avramovic                    : &Mips::ValueMappings[Mips::DPRIdx];
138*1af05df3SPetar Avramovic     OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr});
139*1af05df3SPetar Avramovic     break;
140*1af05df3SPetar Avramovic   }
141021e4c82SPetar Jovanovic   case G_CONSTANT:
142021e4c82SPetar Jovanovic   case G_FRAME_INDEX:
14364c10ba8SPetar Jovanovic   case G_GLOBAL_VALUE:
1445d9b8eedSPetar Avramovic   case G_BRCOND:
145021e4c82SPetar Jovanovic     OperandsMapping =
146021e4c82SPetar Jovanovic         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr});
147021e4c82SPetar Jovanovic     break;
148ce4dd0aeSPetar Jovanovic   case G_ICMP:
149ce4dd0aeSPetar Jovanovic     OperandsMapping =
150ce4dd0aeSPetar Jovanovic         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
151ce4dd0aeSPetar Jovanovic                             &Mips::ValueMappings[Mips::GPRIdx],
152ce4dd0aeSPetar Jovanovic                             &Mips::ValueMappings[Mips::GPRIdx]});
153ce4dd0aeSPetar Jovanovic     break;
15409dff333SPetar Avramovic   case G_SELECT:
15509dff333SPetar Avramovic     OperandsMapping =
15609dff333SPetar Avramovic         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
15709dff333SPetar Avramovic                             &Mips::ValueMappings[Mips::GPRIdx],
15809dff333SPetar Avramovic                             &Mips::ValueMappings[Mips::GPRIdx],
15909dff333SPetar Avramovic                             &Mips::ValueMappings[Mips::GPRIdx]});
16009dff333SPetar Avramovic     break;
161366857a2SPetar Jovanovic   default:
162366857a2SPetar Jovanovic     return getInvalidInstructionMapping();
163366857a2SPetar Jovanovic   }
164366857a2SPetar Jovanovic 
165366857a2SPetar Jovanovic   return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
166366857a2SPetar Jovanovic                                NumOperands);
167366857a2SPetar Jovanovic }
168