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,
271af05df3SPetar Avramovic   PMI_SPR,
281af05df3SPetar Avramovic   PMI_DPR,
29366857a2SPetar Jovanovic   PMI_Min = PMI_GPR,
30366857a2SPetar Jovanovic };
31366857a2SPetar Jovanovic 
32366857a2SPetar Jovanovic RegisterBankInfo::PartialMapping PartMappings[]{
331af05df3SPetar Avramovic     {0, 32, GPRBRegBank},
341af05df3SPetar Avramovic     {0, 32, FPRBRegBank},
351af05df3SPetar Avramovic     {0, 64, FPRBRegBank}
36366857a2SPetar Jovanovic };
37366857a2SPetar Jovanovic 
381af05df3SPetar Avramovic enum ValueMappingIdx {
391af05df3SPetar Avramovic     InvalidIdx = 0,
401af05df3SPetar Avramovic     GPRIdx = 1,
411af05df3SPetar Avramovic     SPRIdx = 4,
421af05df3SPetar Avramovic     DPRIdx = 7
431af05df3SPetar Avramovic };
44366857a2SPetar Jovanovic 
45366857a2SPetar Jovanovic RegisterBankInfo::ValueMapping ValueMappings[] = {
46366857a2SPetar Jovanovic     // invalid
47366857a2SPetar Jovanovic     {nullptr, 0},
481af05df3SPetar Avramovic     // up to 3 operands in GPRs
49366857a2SPetar Jovanovic     {&PartMappings[PMI_GPR - PMI_Min], 1},
50366857a2SPetar Jovanovic     {&PartMappings[PMI_GPR - PMI_Min], 1},
511af05df3SPetar Avramovic     {&PartMappings[PMI_GPR - PMI_Min], 1},
521af05df3SPetar Avramovic     // up to 3 ops operands FPRs - single precission
531af05df3SPetar Avramovic     {&PartMappings[PMI_SPR - PMI_Min], 1},
541af05df3SPetar Avramovic     {&PartMappings[PMI_SPR - PMI_Min], 1},
551af05df3SPetar Avramovic     {&PartMappings[PMI_SPR - PMI_Min], 1},
561af05df3SPetar Avramovic     // up to 3 ops operands FPRs - double precission
571af05df3SPetar Avramovic     {&PartMappings[PMI_DPR - PMI_Min], 1},
581af05df3SPetar Avramovic     {&PartMappings[PMI_DPR - PMI_Min], 1},
591af05df3SPetar Avramovic     {&PartMappings[PMI_DPR - PMI_Min], 1}
601af05df3SPetar 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:
82efcd3c00SPetar Avramovic   case Mips::GP32RegClassID:
83366857a2SPetar Jovanovic     return getRegBank(Mips::GPRBRegBankID);
843dfa368dSPetar Avramovic   case Mips::FGRCCRegClassID:
85afa3afa3SPetar Avramovic   case Mips::FGR32RegClassID:
863dfa368dSPetar Avramovic   case Mips::FGR64RegClassID:
873dfa368dSPetar Avramovic   case Mips::AFGR64RegClassID:
883dfa368dSPetar Avramovic     return getRegBank(Mips::FPRBRegBankID);
89366857a2SPetar Jovanovic   default:
90366857a2SPetar Jovanovic     llvm_unreachable("Register class not supported");
91366857a2SPetar Jovanovic   }
92366857a2SPetar Jovanovic }
93366857a2SPetar Jovanovic 
94366857a2SPetar Jovanovic const RegisterBankInfo::InstructionMapping &
95366857a2SPetar Jovanovic MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
96366857a2SPetar Jovanovic 
97366857a2SPetar Jovanovic   unsigned Opc = MI.getOpcode();
981af05df3SPetar Avramovic   const MachineFunction &MF = *MI.getParent()->getParent();
991af05df3SPetar Avramovic   const MachineRegisterInfo &MRI = MF.getRegInfo();
100366857a2SPetar Jovanovic 
101366857a2SPetar Jovanovic   const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
102366857a2SPetar Jovanovic   if (Mapping.isValid())
103366857a2SPetar Jovanovic     return Mapping;
104366857a2SPetar Jovanovic 
105366857a2SPetar Jovanovic   using namespace TargetOpcode;
106366857a2SPetar Jovanovic 
107366857a2SPetar Jovanovic   unsigned NumOperands = MI.getNumOperands();
108366857a2SPetar Jovanovic   const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
109366857a2SPetar Jovanovic 
110366857a2SPetar Jovanovic   switch (Opc) {
1117cecadb9SPetar Avramovic   case G_TRUNC:
112366857a2SPetar Jovanovic   case G_ADD:
1137cecadb9SPetar Avramovic   case G_SUB:
11456dc218dSPetar Avramovic   case G_MUL:
115a48285a1SPetar Avramovic   case G_UMULH:
116021e4c82SPetar Jovanovic   case G_LOAD:
117021e4c82SPetar Jovanovic   case G_STORE:
11879df8596SPetar Avramovic   case G_ZEXTLOAD:
11979df8596SPetar Avramovic   case G_SEXTLOAD:
120021e4c82SPetar Jovanovic   case G_GEP:
1213b953c37SPetar Jovanovic   case G_AND:
1223b953c37SPetar Jovanovic   case G_OR:
1233b953c37SPetar Jovanovic   case G_XOR:
1243b953c37SPetar Jovanovic   case G_SHL:
1253b953c37SPetar Jovanovic   case G_ASHR:
1263b953c37SPetar Jovanovic   case G_LSHR:
1270a5e4eb7SPetar Avramovic   case G_SDIV:
1280a5e4eb7SPetar Avramovic   case G_UDIV:
1290a5e4eb7SPetar Avramovic   case G_SREM:
1300a5e4eb7SPetar Avramovic   case G_UREM:
131366857a2SPetar Jovanovic     OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx];
132366857a2SPetar Jovanovic     break;
133afa3afa3SPetar Avramovic   case G_FADD:
134afa3afa3SPetar Avramovic   case G_FSUB:
135afa3afa3SPetar Avramovic   case G_FMUL:
1360a1fd355SPetar Avramovic   case G_FDIV:
13781132ce0SPetar Avramovic   case G_FABS:
13881132ce0SPetar Avramovic   case G_FSQRT:{
139afa3afa3SPetar Avramovic     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
140afa3afa3SPetar Avramovic     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
141afa3afa3SPetar Avramovic     OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
142afa3afa3SPetar Avramovic                                  : &Mips::ValueMappings[Mips::DPRIdx];
143afa3afa3SPetar Avramovic     break;
144afa3afa3SPetar Avramovic   }
1451af05df3SPetar Avramovic   case G_FCONSTANT: {
146afa3afa3SPetar Avramovic     unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
147afa3afa3SPetar Avramovic     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
1481af05df3SPetar Avramovic     const RegisterBankInfo::ValueMapping *FPRValueMapping =
1491af05df3SPetar Avramovic         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
1501af05df3SPetar Avramovic                    : &Mips::ValueMappings[Mips::DPRIdx];
1511af05df3SPetar Avramovic     OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr});
1521af05df3SPetar Avramovic     break;
1531af05df3SPetar Avramovic   }
15422e99c43SPetar Avramovic   case G_FCMP: {
15522e99c43SPetar Avramovic     unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
15622e99c43SPetar Avramovic     assert((Size == 32 || Size == 64) && "Unsupported floating point size");
15722e99c43SPetar Avramovic     const RegisterBankInfo::ValueMapping *FPRValueMapping =
15822e99c43SPetar Avramovic         Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
15922e99c43SPetar Avramovic                    : &Mips::ValueMappings[Mips::DPRIdx];
16022e99c43SPetar Avramovic     OperandsMapping =
16122e99c43SPetar Avramovic         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
16222e99c43SPetar Avramovic                             FPRValueMapping, FPRValueMapping});
16322e99c43SPetar Avramovic     break;
16422e99c43SPetar Avramovic   }
165a7d00064SPetar Avramovic   case G_FPEXT:
166a7d00064SPetar Avramovic     OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx],
167a7d00064SPetar Avramovic                                           &Mips::ValueMappings[Mips::SPRIdx]});
168a7d00064SPetar Avramovic     break;
169a7d00064SPetar Avramovic   case G_FPTRUNC:
170a7d00064SPetar Avramovic     OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx],
171a7d00064SPetar Avramovic                                           &Mips::ValueMappings[Mips::DPRIdx]});
172a7d00064SPetar Avramovic     break;
1734b4dae1cSPetar Avramovic   case G_FPTOSI: {
1744b4dae1cSPetar Avramovic     unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
175*ddd056c9SFangrui Song     assert((MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 32) &&
176*ddd056c9SFangrui Song            "Unsupported integer size");
1774b4dae1cSPetar Avramovic     assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size");
1784b4dae1cSPetar Avramovic     OperandsMapping = getOperandsMapping({
1794b4dae1cSPetar Avramovic         &Mips::ValueMappings[Mips::GPRIdx],
1804b4dae1cSPetar Avramovic         SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
1814b4dae1cSPetar Avramovic                      : &Mips::ValueMappings[Mips::DPRIdx],
1824b4dae1cSPetar Avramovic     });
1834b4dae1cSPetar Avramovic     break;
1844b4dae1cSPetar Avramovic   }
185153bd24eSPetar Avramovic   case G_SITOFP: {
186153bd24eSPetar Avramovic     unsigned SizeInt = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
187153bd24eSPetar Avramovic     unsigned SizeFP = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
188*ddd056c9SFangrui Song     (void)SizeInt;
189153bd24eSPetar Avramovic     assert((SizeInt == 32) && "Unsupported integer size");
190153bd24eSPetar Avramovic     assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size");
191153bd24eSPetar Avramovic     OperandsMapping =
192153bd24eSPetar Avramovic         getOperandsMapping({SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
193153bd24eSPetar Avramovic                                          : &Mips::ValueMappings[Mips::DPRIdx],
194153bd24eSPetar Avramovic                             &Mips::ValueMappings[Mips::GPRIdx]});
195153bd24eSPetar Avramovic     break;
196153bd24eSPetar Avramovic   }
197021e4c82SPetar Jovanovic   case G_CONSTANT:
198021e4c82SPetar Jovanovic   case G_FRAME_INDEX:
19964c10ba8SPetar Jovanovic   case G_GLOBAL_VALUE:
2005d9b8eedSPetar Avramovic   case G_BRCOND:
201021e4c82SPetar Jovanovic     OperandsMapping =
202021e4c82SPetar Jovanovic         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr});
203021e4c82SPetar Jovanovic     break;
204ce4dd0aeSPetar Jovanovic   case G_ICMP:
205ce4dd0aeSPetar Jovanovic     OperandsMapping =
206ce4dd0aeSPetar Jovanovic         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr,
207ce4dd0aeSPetar Jovanovic                             &Mips::ValueMappings[Mips::GPRIdx],
208ce4dd0aeSPetar Jovanovic                             &Mips::ValueMappings[Mips::GPRIdx]});
209ce4dd0aeSPetar Jovanovic     break;
21009dff333SPetar Avramovic   case G_SELECT:
21109dff333SPetar Avramovic     OperandsMapping =
21209dff333SPetar Avramovic         getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
21309dff333SPetar Avramovic                             &Mips::ValueMappings[Mips::GPRIdx],
21409dff333SPetar Avramovic                             &Mips::ValueMappings[Mips::GPRIdx],
21509dff333SPetar Avramovic                             &Mips::ValueMappings[Mips::GPRIdx]});
21609dff333SPetar Avramovic     break;
217366857a2SPetar Jovanovic   default:
218366857a2SPetar Jovanovic     return getInvalidInstructionMapping();
219366857a2SPetar Jovanovic   }
220366857a2SPetar Jovanovic 
221366857a2SPetar Jovanovic   return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
222366857a2SPetar Jovanovic                                NumOperands);
223366857a2SPetar Jovanovic }
224