122274934SDiana Picus //===- ARMRegisterBankInfo.cpp -----------------------------------*- C++ -*-==//
222274934SDiana Picus //
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
622274934SDiana Picus //
722274934SDiana Picus //===----------------------------------------------------------------------===//
822274934SDiana Picus /// \file
922274934SDiana Picus /// This file implements the targeting of the RegisterBankInfo class for ARM.
1022274934SDiana Picus /// \todo This should be generated by TableGen.
1122274934SDiana Picus //===----------------------------------------------------------------------===//
1222274934SDiana Picus 
1322274934SDiana Picus #include "ARMRegisterBankInfo.h"
14812caee6SDiana Picus #include "ARMInstrInfo.h" // For the register classes
159b32faa8SDiana Picus #include "ARMSubtarget.h"
1622274934SDiana Picus #include "llvm/CodeGen/MachineRegisterInfo.h"
17cb216076SMircea Trofin #include "llvm/CodeGen/RegisterBank.h"
18cb216076SMircea Trofin #include "llvm/CodeGen/RegisterBankInfo.h"
19b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
2022274934SDiana Picus 
21c3ac5667SDaniel Sanders #define GET_TARGET_REGBANK_IMPL
22c3ac5667SDaniel Sanders #include "ARMGenRegisterBank.inc"
23c3ac5667SDaniel Sanders 
2422274934SDiana Picus using namespace llvm;
2522274934SDiana Picus 
26812caee6SDiana Picus // FIXME: TableGen this.
27812caee6SDiana Picus // If it grows too much and TableGen still isn't ready to do the job, extract it
28812caee6SDiana Picus // into an ARMGenRegisterBankInfo.def (similar to AArch64).
29812caee6SDiana Picus namespace llvm {
30812caee6SDiana Picus namespace ARM {
3138699dbaSDiana Picus enum PartialMappingIdx {
3238699dbaSDiana Picus   PMI_GPR,
3338699dbaSDiana Picus   PMI_SPR,
3438699dbaSDiana Picus   PMI_DPR,
3538699dbaSDiana Picus   PMI_Min = PMI_GPR,
3638699dbaSDiana Picus };
37812caee6SDiana Picus 
3838699dbaSDiana Picus RegisterBankInfo::PartialMapping PartMappings[]{
3938699dbaSDiana Picus     // GPR Partial Mapping
4038699dbaSDiana Picus     {0, 32, GPRRegBank},
4138699dbaSDiana Picus     // SPR Partial Mapping
4238699dbaSDiana Picus     {0, 32, FPRRegBank},
4338699dbaSDiana Picus     // DPR Partial Mapping
4438699dbaSDiana Picus     {0, 64, FPRRegBank},
4538699dbaSDiana Picus };
4638699dbaSDiana Picus 
4738699dbaSDiana Picus #ifndef NDEBUG
checkPartMapping(const RegisterBankInfo::PartialMapping & PM,unsigned Start,unsigned Length,unsigned RegBankID)4838699dbaSDiana Picus static bool checkPartMapping(const RegisterBankInfo::PartialMapping &PM,
4938699dbaSDiana Picus                              unsigned Start, unsigned Length,
5038699dbaSDiana Picus                              unsigned RegBankID) {
5138699dbaSDiana Picus   return PM.StartIdx == Start && PM.Length == Length &&
5238699dbaSDiana Picus          PM.RegBank->getID() == RegBankID;
5338699dbaSDiana Picus }
5438699dbaSDiana Picus 
checkPartialMappings()5538699dbaSDiana Picus static void checkPartialMappings() {
5638699dbaSDiana Picus   assert(
5738699dbaSDiana Picus       checkPartMapping(PartMappings[PMI_GPR - PMI_Min], 0, 32, GPRRegBankID) &&
5838699dbaSDiana Picus       "Wrong mapping for GPR");
5938699dbaSDiana Picus   assert(
6038699dbaSDiana Picus       checkPartMapping(PartMappings[PMI_SPR - PMI_Min], 0, 32, FPRRegBankID) &&
6138699dbaSDiana Picus       "Wrong mapping for SPR");
6238699dbaSDiana Picus   assert(
6338699dbaSDiana Picus       checkPartMapping(PartMappings[PMI_DPR - PMI_Min], 0, 64, FPRRegBankID) &&
6438699dbaSDiana Picus       "Wrong mapping for DPR");
6538699dbaSDiana Picus }
6638699dbaSDiana Picus #endif
6738699dbaSDiana Picus 
6838699dbaSDiana Picus enum ValueMappingIdx {
6938699dbaSDiana Picus   InvalidIdx = 0,
7038699dbaSDiana Picus   GPR3OpsIdx = 1,
7138699dbaSDiana Picus   SPR3OpsIdx = 4,
7238699dbaSDiana Picus   DPR3OpsIdx = 7,
7338699dbaSDiana Picus };
7438699dbaSDiana Picus 
75812caee6SDiana Picus RegisterBankInfo::ValueMapping ValueMappings[] = {
7638699dbaSDiana Picus     // invalid
7738699dbaSDiana Picus     {nullptr, 0},
7838699dbaSDiana Picus     // 3 ops in GPRs
7938699dbaSDiana Picus     {&PartMappings[PMI_GPR - PMI_Min], 1},
8038699dbaSDiana Picus     {&PartMappings[PMI_GPR - PMI_Min], 1},
8138699dbaSDiana Picus     {&PartMappings[PMI_GPR - PMI_Min], 1},
8238699dbaSDiana Picus     // 3 ops in SPRs
8338699dbaSDiana Picus     {&PartMappings[PMI_SPR - PMI_Min], 1},
8438699dbaSDiana Picus     {&PartMappings[PMI_SPR - PMI_Min], 1},
8538699dbaSDiana Picus     {&PartMappings[PMI_SPR - PMI_Min], 1},
8638699dbaSDiana Picus     // 3 ops in DPRs
8738699dbaSDiana Picus     {&PartMappings[PMI_DPR - PMI_Min], 1},
8838699dbaSDiana Picus     {&PartMappings[PMI_DPR - PMI_Min], 1},
8938699dbaSDiana Picus     {&PartMappings[PMI_DPR - PMI_Min], 1}};
9038699dbaSDiana Picus 
9138699dbaSDiana Picus #ifndef NDEBUG
checkValueMapping(const RegisterBankInfo::ValueMapping & VM,RegisterBankInfo::PartialMapping * BreakDown)9238699dbaSDiana Picus static bool checkValueMapping(const RegisterBankInfo::ValueMapping &VM,
9338699dbaSDiana Picus                               RegisterBankInfo::PartialMapping *BreakDown) {
9438699dbaSDiana Picus   return VM.NumBreakDowns == 1 && VM.BreakDown == BreakDown;
9538699dbaSDiana Picus }
9638699dbaSDiana Picus 
checkValueMappings()9738699dbaSDiana Picus static void checkValueMappings() {
9838699dbaSDiana Picus   assert(checkValueMapping(ValueMappings[GPR3OpsIdx],
9938699dbaSDiana Picus                            &PartMappings[PMI_GPR - PMI_Min]) &&
10038699dbaSDiana Picus          "Wrong value mapping for 3 GPR ops instruction");
10138699dbaSDiana Picus   assert(checkValueMapping(ValueMappings[GPR3OpsIdx + 1],
10238699dbaSDiana Picus                            &PartMappings[PMI_GPR - PMI_Min]) &&
10338699dbaSDiana Picus          "Wrong value mapping for 3 GPR ops instruction");
10438699dbaSDiana Picus   assert(checkValueMapping(ValueMappings[GPR3OpsIdx + 2],
10538699dbaSDiana Picus                            &PartMappings[PMI_GPR - PMI_Min]) &&
10638699dbaSDiana Picus          "Wrong value mapping for 3 GPR ops instruction");
10738699dbaSDiana Picus 
10838699dbaSDiana Picus   assert(checkValueMapping(ValueMappings[SPR3OpsIdx],
10938699dbaSDiana Picus                            &PartMappings[PMI_SPR - PMI_Min]) &&
11038699dbaSDiana Picus          "Wrong value mapping for 3 SPR ops instruction");
11138699dbaSDiana Picus   assert(checkValueMapping(ValueMappings[SPR3OpsIdx + 1],
11238699dbaSDiana Picus                            &PartMappings[PMI_SPR - PMI_Min]) &&
11338699dbaSDiana Picus          "Wrong value mapping for 3 SPR ops instruction");
11438699dbaSDiana Picus   assert(checkValueMapping(ValueMappings[SPR3OpsIdx + 2],
11538699dbaSDiana Picus                            &PartMappings[PMI_SPR - PMI_Min]) &&
11638699dbaSDiana Picus          "Wrong value mapping for 3 SPR ops instruction");
11738699dbaSDiana Picus 
11838699dbaSDiana Picus   assert(checkValueMapping(ValueMappings[DPR3OpsIdx],
11938699dbaSDiana Picus                            &PartMappings[PMI_DPR - PMI_Min]) &&
12038699dbaSDiana Picus          "Wrong value mapping for 3 DPR ops instruction");
12138699dbaSDiana Picus   assert(checkValueMapping(ValueMappings[DPR3OpsIdx + 1],
12238699dbaSDiana Picus                            &PartMappings[PMI_DPR - PMI_Min]) &&
12338699dbaSDiana Picus          "Wrong value mapping for 3 DPR ops instruction");
12438699dbaSDiana Picus   assert(checkValueMapping(ValueMappings[DPR3OpsIdx + 2],
12538699dbaSDiana Picus                            &PartMappings[PMI_DPR - PMI_Min]) &&
12638699dbaSDiana Picus          "Wrong value mapping for 3 DPR ops instruction");
12738699dbaSDiana Picus }
12838699dbaSDiana Picus #endif
129812caee6SDiana Picus } // end namespace arm
130812caee6SDiana Picus } // end namespace llvm
131812caee6SDiana Picus 
ARMRegisterBankInfo(const TargetRegisterInfo & TRI)132*62128719SKazu Hirata ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI) {
133812caee6SDiana Picus   // We have only one set of register banks, whatever the subtarget
134812caee6SDiana Picus   // is. Therefore, the initialization of the RegBanks table should be
135812caee6SDiana Picus   // done only once. Indeed the table of all register banks
136812caee6SDiana Picus   // (ARM::RegBanks) is unique in the compiler. At some point, it
137812caee6SDiana Picus   // will get tablegen'ed and the whole constructor becomes empty.
138ae391054SHuihui Zhang   static llvm::once_flag InitializeRegisterBankFlag;
139812caee6SDiana Picus 
140ae391054SHuihui Zhang   static auto InitializeRegisterBankOnce = [&]() {
141812caee6SDiana Picus     const RegisterBank &RBGPR = getRegBank(ARM::GPRRegBankID);
142812caee6SDiana Picus     (void)RBGPR;
143812caee6SDiana Picus     assert(&ARM::GPRRegBank == &RBGPR && "The order in RegBanks is messed up");
144b7391dd3SDaniel Sanders 
145b7391dd3SDaniel Sanders     // Initialize the GPR bank.
146812caee6SDiana Picus     assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRRegClassID)) &&
147812caee6SDiana Picus            "Subclass not added?");
148812caee6SDiana Picus     assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRwithAPSRRegClassID)) &&
149812caee6SDiana Picus            "Subclass not added?");
150812caee6SDiana Picus     assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnopcRegClassID)) &&
151812caee6SDiana Picus            "Subclass not added?");
152812caee6SDiana Picus     assert(RBGPR.covers(*TRI.getRegClass(ARM::rGPRRegClassID)) &&
153812caee6SDiana Picus            "Subclass not added?");
154812caee6SDiana Picus     assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPRRegClassID)) &&
155812caee6SDiana Picus            "Subclass not added?");
156812caee6SDiana Picus     assert(RBGPR.covers(*TRI.getRegClass(ARM::tcGPRRegClassID)) &&
157812caee6SDiana Picus            "Subclass not added?");
158df8ed392SKristof Beyls     assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnoip_and_tcGPRRegClassID)) &&
159812caee6SDiana Picus            "Subclass not added?");
160df8ed392SKristof Beyls     assert(RBGPR.covers(*TRI.getRegClass(
161df8ed392SKristof Beyls                ARM::tGPREven_and_GPRnoip_and_tcGPRRegClassID)) &&
162286e1d2cSSimon Tatham            "Subclass not added?");
163286e1d2cSSimon Tatham     assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPROdd_and_tcGPRRegClassID)) &&
164286e1d2cSSimon Tatham            "Subclass not added?");
165812caee6SDiana Picus     assert(RBGPR.getSize() == 32 && "GPRs should hold up to 32-bit");
16638699dbaSDiana Picus 
16738699dbaSDiana Picus #ifndef NDEBUG
16838699dbaSDiana Picus     ARM::checkPartialMappings();
16938699dbaSDiana Picus     ARM::checkValueMappings();
17038699dbaSDiana Picus #endif
171ae391054SHuihui Zhang   };
172ae391054SHuihui Zhang 
173ae391054SHuihui Zhang   llvm::call_once(InitializeRegisterBankFlag, InitializeRegisterBankOnce);
174812caee6SDiana Picus }
175812caee6SDiana Picus 
17621309eafSMatt Arsenault const RegisterBank &
getRegBankFromRegClass(const TargetRegisterClass & RC,LLT) const17721309eafSMatt Arsenault ARMRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
17821309eafSMatt Arsenault                                             LLT) const {
179812caee6SDiana Picus   using namespace ARM;
180812caee6SDiana Picus 
181812caee6SDiana Picus   switch (RC.getID()) {
182812caee6SDiana Picus   case GPRRegClassID:
183e79d656cSRoman Tereshin   case GPRwithAPSRRegClassID:
184df8ed392SKristof Beyls   case GPRnoipRegClassID:
1858b6c6bedSDiana Picus   case GPRnopcRegClassID:
186df8ed392SKristof Beyls   case GPRnoip_and_GPRnopcRegClassID:
187e79d656cSRoman Tereshin   case rGPRRegClassID:
18894db2e28SDiana Picus   case GPRspRegClassID:
189df8ed392SKristof Beyls   case GPRnoip_and_tcGPRRegClassID:
190e79d656cSRoman Tereshin   case tcGPRRegClassID:
1911f432f99SDiana Picus   case tGPRRegClassID:
1927bd5c55cSMikhail Maltsev   case tGPREvenRegClassID:
1937bd5c55cSMikhail Maltsev   case tGPROddRegClassID:
1947bd5c55cSMikhail Maltsev   case tGPR_and_tGPREvenRegClassID:
1957bd5c55cSMikhail Maltsev   case tGPR_and_tGPROddRegClassID:
1967bd5c55cSMikhail Maltsev   case tGPREven_and_tcGPRRegClassID:
197df8ed392SKristof Beyls   case tGPREven_and_GPRnoip_and_tcGPRRegClassID:
1987bd5c55cSMikhail Maltsev   case tGPROdd_and_tcGPRRegClassID:
199812caee6SDiana Picus     return getRegBank(ARM::GPRRegBankID);
200e79d656cSRoman Tereshin   case HPRRegClassID:
2014fa83c03SDiana Picus   case SPR_8RegClassID:
2024fa83c03SDiana Picus   case SPRRegClassID:
2037f82c870SDiana Picus   case DPR_8RegClassID:
2047f82c870SDiana Picus   case DPRRegClassID:
205e79d656cSRoman Tereshin   case QPRRegClassID:
2064fa83c03SDiana Picus     return getRegBank(ARM::FPRRegBankID);
207812caee6SDiana Picus   default:
208812caee6SDiana Picus     llvm_unreachable("Unsupported register kind");
209812caee6SDiana Picus   }
210812caee6SDiana Picus 
211812caee6SDiana Picus   llvm_unreachable("Switch should handle all register classes");
212812caee6SDiana Picus }
213812caee6SDiana Picus 
214245994d9SQuentin Colombet const RegisterBankInfo::InstructionMapping &
getInstrMapping(const MachineInstr & MI) const215812caee6SDiana Picus ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
216812caee6SDiana Picus   auto Opc = MI.getOpcode();
217812caee6SDiana Picus 
218812caee6SDiana Picus   // Try the default logic for non-generic instructions that are either copies
219812caee6SDiana Picus   // or already have some operands assigned to banks.
220efd8a84cSAditya Nandakumar   if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
221245994d9SQuentin Colombet     const InstructionMapping &Mapping = getInstrMappingImpl(MI);
222812caee6SDiana Picus     if (Mapping.isValid())
223812caee6SDiana Picus       return Mapping;
224812caee6SDiana Picus   }
225812caee6SDiana Picus 
226519807f7SDiana Picus   using namespace TargetOpcode;
227519807f7SDiana Picus 
2287f82c870SDiana Picus   const MachineFunction &MF = *MI.getParent()->getParent();
2297f82c870SDiana Picus   const MachineRegisterInfo &MRI = MF.getRegInfo();
230812caee6SDiana Picus   unsigned NumOperands = MI.getNumOperands();
23138699dbaSDiana Picus   const ValueMapping *OperandsMapping = &ARM::ValueMappings[ARM::GPR3OpsIdx];
232519807f7SDiana Picus 
233519807f7SDiana Picus   switch (Opc) {
234519807f7SDiana Picus   case G_ADD:
23525f08a17SEli Friedman   case G_SUB: {
23625f08a17SEli Friedman     // Integer operations where the source and destination are in the
23725f08a17SEli Friedman     // same register class.
23825f08a17SEli Friedman     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
23925f08a17SEli Friedman     OperandsMapping = Ty.getSizeInBits() == 64
24025f08a17SEli Friedman                           ? &ARM::ValueMappings[ARM::DPR3OpsIdx]
24125f08a17SEli Friedman                           : &ARM::ValueMappings[ARM::GPR3OpsIdx];
24225f08a17SEli Friedman     break;
24325f08a17SEli Friedman   }
24449472ff1SDiana Picus   case G_MUL:
2458445858aSDiana Picus   case G_AND:
246eeb0aad8SDiana Picus   case G_OR:
2470196427bSDiana Picus   case G_XOR:
248a81a4b17SDiana Picus   case G_LSHR:
249a81a4b17SDiana Picus   case G_ASHR:
250a81a4b17SDiana Picus   case G_SHL:
251b70e88bdSDiana Picus   case G_SDIV:
252b70e88bdSDiana Picus   case G_UDIV:
2538b6c6bedSDiana Picus   case G_SEXT:
2548b6c6bedSDiana Picus   case G_ZEXT:
255657bfd33SDiana Picus   case G_ANYEXT:
256e74c5b96SDaniel Sanders   case G_PTR_ADD:
25728a6d0e6SDiana Picus   case G_INTTOPTR:
25828a6d0e6SDiana Picus   case G_PTRTOINT:
2590528e2cfSDiana Picus   case G_CTLZ:
260519807f7SDiana Picus     // FIXME: We're abusing the fact that everything lives in a GPR for now; in
261519807f7SDiana Picus     // the real world we would use different mappings.
26238699dbaSDiana Picus     OperandsMapping = &ARM::ValueMappings[ARM::GPR3OpsIdx];
263519807f7SDiana Picus     break;
26475ce852aSDiana Picus   case G_TRUNC: {
26575ce852aSDiana Picus     // In some cases we may end up with a G_TRUNC from a 64-bit value to a
26675ce852aSDiana Picus     // 32-bit value. This isn't a real floating point trunc (that would be a
26775ce852aSDiana Picus     // G_FPTRUNC). Instead it is an integer trunc in disguise, which can appear
26875ce852aSDiana Picus     // because the legalizer doesn't distinguish between integer and floating
26975ce852aSDiana Picus     // point values so it may leave some 64-bit integers un-narrowed. Until we
27075ce852aSDiana Picus     // have a more principled solution that doesn't let such things sneak all
27175ce852aSDiana Picus     // the way to this point, just map the source to a DPR and the destination
27275ce852aSDiana Picus     // to a GPR.
27375ce852aSDiana Picus     LLT LargeTy = MRI.getType(MI.getOperand(1).getReg());
27475ce852aSDiana Picus     OperandsMapping =
27575ce852aSDiana Picus         LargeTy.getSizeInBits() <= 32
27675ce852aSDiana Picus             ? &ARM::ValueMappings[ARM::GPR3OpsIdx]
27775ce852aSDiana Picus             : getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
27875ce852aSDiana Picus                                   &ARM::ValueMappings[ARM::DPR3OpsIdx]});
27975ce852aSDiana Picus     break;
28075ce852aSDiana Picus   }
2817f82c870SDiana Picus   case G_LOAD:
2826860a60cSDiana Picus   case G_STORE: {
2836860a60cSDiana Picus     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
28438699dbaSDiana Picus     OperandsMapping =
28538699dbaSDiana Picus         Ty.getSizeInBits() == 64
28638699dbaSDiana Picus             ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
28738699dbaSDiana Picus                                   &ARM::ValueMappings[ARM::GPR3OpsIdx]})
28838699dbaSDiana Picus             : &ARM::ValueMappings[ARM::GPR3OpsIdx];
2897f82c870SDiana Picus     break;
2906860a60cSDiana Picus   }
2915cde1ccbSJaved Absar   case G_FADD:
2929faa09b2SDiana Picus   case G_FSUB:
293c01f7f13SDiana Picus   case G_FMUL:
2940ed7513cSDiana Picus   case G_FDIV:
2950ed7513cSDiana Picus   case G_FNEG: {
2966860a60cSDiana Picus     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
29738699dbaSDiana Picus     OperandsMapping =Ty.getSizeInBits() == 64
29838699dbaSDiana Picus                           ? &ARM::ValueMappings[ARM::DPR3OpsIdx]
29938699dbaSDiana Picus                           : &ARM::ValueMappings[ARM::SPR3OpsIdx];
3004fa83c03SDiana Picus     break;
3016860a60cSDiana Picus   }
3022dc54056SDiana Picus   case G_FMA: {
3032dc54056SDiana Picus     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
3042dc54056SDiana Picus     OperandsMapping =
3052dc54056SDiana Picus         Ty.getSizeInBits() == 64
3062dc54056SDiana Picus             ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
3072dc54056SDiana Picus                                   &ARM::ValueMappings[ARM::DPR3OpsIdx],
3082dc54056SDiana Picus                                   &ARM::ValueMappings[ARM::DPR3OpsIdx],
3092dc54056SDiana Picus                                   &ARM::ValueMappings[ARM::DPR3OpsIdx]})
3102dc54056SDiana Picus             : getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx],
3112dc54056SDiana Picus                                   &ARM::ValueMappings[ARM::SPR3OpsIdx],
3122dc54056SDiana Picus                                   &ARM::ValueMappings[ARM::SPR3OpsIdx],
3132dc54056SDiana Picus                                   &ARM::ValueMappings[ARM::SPR3OpsIdx]});
3142dc54056SDiana Picus     break;
3152dc54056SDiana Picus   }
316c62a1623SDiana Picus   case G_FPEXT: {
317c62a1623SDiana Picus     LLT ToTy = MRI.getType(MI.getOperand(0).getReg());
318c62a1623SDiana Picus     LLT FromTy = MRI.getType(MI.getOperand(1).getReg());
319c62a1623SDiana Picus     if (ToTy.getSizeInBits() == 64 && FromTy.getSizeInBits() == 32)
320c62a1623SDiana Picus       OperandsMapping =
321c62a1623SDiana Picus           getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
322c62a1623SDiana Picus                               &ARM::ValueMappings[ARM::SPR3OpsIdx]});
323c62a1623SDiana Picus     break;
324c62a1623SDiana Picus   }
325c62a1623SDiana Picus   case G_FPTRUNC: {
326c62a1623SDiana Picus     LLT ToTy = MRI.getType(MI.getOperand(0).getReg());
327c62a1623SDiana Picus     LLT FromTy = MRI.getType(MI.getOperand(1).getReg());
328c62a1623SDiana Picus     if (ToTy.getSizeInBits() == 32 && FromTy.getSizeInBits() == 64)
329c62a1623SDiana Picus       OperandsMapping =
330c62a1623SDiana Picus           getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx],
331c62a1623SDiana Picus                               &ARM::ValueMappings[ARM::DPR3OpsIdx]});
332c62a1623SDiana Picus     break;
333c62a1623SDiana Picus   }
334a2da0302SDiana Picus   case G_FPTOSI:
335a2da0302SDiana Picus   case G_FPTOUI: {
336a2da0302SDiana Picus     LLT ToTy = MRI.getType(MI.getOperand(0).getReg());
337a2da0302SDiana Picus     LLT FromTy = MRI.getType(MI.getOperand(1).getReg());
338a2da0302SDiana Picus     if ((FromTy.getSizeInBits() == 32 || FromTy.getSizeInBits() == 64) &&
339a2da0302SDiana Picus         ToTy.getSizeInBits() == 32)
340a2da0302SDiana Picus       OperandsMapping =
341a2da0302SDiana Picus           FromTy.getSizeInBits() == 64
342a2da0302SDiana Picus               ? getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
343a2da0302SDiana Picus                                     &ARM::ValueMappings[ARM::DPR3OpsIdx]})
344a2da0302SDiana Picus               : getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
345a2da0302SDiana Picus                                     &ARM::ValueMappings[ARM::SPR3OpsIdx]});
346a2da0302SDiana Picus     break;
347a2da0302SDiana Picus   }
3482a5b9620SDiana Picus   case G_SITOFP:
3492a5b9620SDiana Picus   case G_UITOFP: {
3502a5b9620SDiana Picus     LLT ToTy = MRI.getType(MI.getOperand(0).getReg());
3512a5b9620SDiana Picus     LLT FromTy = MRI.getType(MI.getOperand(1).getReg());
3522a5b9620SDiana Picus     if (FromTy.getSizeInBits() == 32 &&
3532a5b9620SDiana Picus         (ToTy.getSizeInBits() == 32 || ToTy.getSizeInBits() == 64))
3542a5b9620SDiana Picus       OperandsMapping =
3552a5b9620SDiana Picus           ToTy.getSizeInBits() == 64
3562a5b9620SDiana Picus               ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
3572a5b9620SDiana Picus                                     &ARM::ValueMappings[ARM::GPR3OpsIdx]})
3582a5b9620SDiana Picus               : getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx],
3592a5b9620SDiana Picus                                     &ARM::ValueMappings[ARM::GPR3OpsIdx]});
3602a5b9620SDiana Picus     break;
3612a5b9620SDiana Picus   }
362165846b0SDiana Picus   case G_FCONSTANT: {
363165846b0SDiana Picus     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
364165846b0SDiana Picus     OperandsMapping = getOperandsMapping(
365165846b0SDiana Picus         {Ty.getSizeInBits() == 64 ? &ARM::ValueMappings[ARM::DPR3OpsIdx]
366165846b0SDiana Picus                                   : &ARM::ValueMappings[ARM::SPR3OpsIdx],
367165846b0SDiana Picus          nullptr});
368165846b0SDiana Picus     break;
369165846b0SDiana Picus   }
3705b851455SDiana Picus   case G_CONSTANT:
371519807f7SDiana Picus   case G_FRAME_INDEX:
372a5d6518eSDiana Picus   case G_GLOBAL_VALUE:
37338699dbaSDiana Picus     OperandsMapping =
37438699dbaSDiana Picus         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr});
375519807f7SDiana Picus     break;
3767145d22fSDiana Picus   case G_SELECT: {
3776860a60cSDiana Picus     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
378f69d7b04SDiana Picus     (void)Ty;
3797145d22fSDiana Picus     LLT Ty2 = MRI.getType(MI.getOperand(1).getReg());
3807145d22fSDiana Picus     (void)Ty2;
3817145d22fSDiana Picus     assert(Ty.getSizeInBits() == 32 && "Unsupported size for G_SELECT");
3827145d22fSDiana Picus     assert(Ty2.getSizeInBits() == 1 && "Unsupported size for G_SELECT");
3837145d22fSDiana Picus     OperandsMapping =
3847145d22fSDiana Picus         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
3857145d22fSDiana Picus                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
3867145d22fSDiana Picus                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
3877145d22fSDiana Picus                             &ARM::ValueMappings[ARM::GPR3OpsIdx]});
3887145d22fSDiana Picus     break;
3897145d22fSDiana Picus   }
390621894acSDiana Picus   case G_ICMP: {
391621894acSDiana Picus     LLT Ty2 = MRI.getType(MI.getOperand(2).getReg());
392621894acSDiana Picus     (void)Ty2;
393621894acSDiana Picus     assert(Ty2.getSizeInBits() == 32 && "Unsupported size for G_ICMP");
394621894acSDiana Picus     OperandsMapping =
395621894acSDiana Picus         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr,
396621894acSDiana Picus                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
397621894acSDiana Picus                             &ARM::ValueMappings[ARM::GPR3OpsIdx]});
398621894acSDiana Picus     break;
399621894acSDiana Picus   }
400c3a9c347SDiana Picus   case G_FCMP: {
4016860a60cSDiana Picus     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
402f69d7b04SDiana Picus     (void)Ty;
403c3a9c347SDiana Picus     LLT Ty1 = MRI.getType(MI.getOperand(2).getReg());
404c3a9c347SDiana Picus     LLT Ty2 = MRI.getType(MI.getOperand(3).getReg());
405c3a9c347SDiana Picus     (void)Ty2;
406c3a9c347SDiana Picus     assert(Ty.getSizeInBits() == 1 && "Unsupported size for G_FCMP");
407069da27fSDiana Picus     assert(Ty1.getSizeInBits() == Ty2.getSizeInBits() &&
408069da27fSDiana Picus            "Mismatched operand sizes for G_FCMP");
409069da27fSDiana Picus 
410069da27fSDiana Picus     unsigned Size = Ty1.getSizeInBits();
411069da27fSDiana Picus     assert((Size == 32 || Size == 64) && "Unsupported size for G_FCMP");
412069da27fSDiana Picus 
413069da27fSDiana Picus     auto FPRValueMapping = Size == 32 ? &ARM::ValueMappings[ARM::SPR3OpsIdx]
414069da27fSDiana Picus                                       : &ARM::ValueMappings[ARM::DPR3OpsIdx];
415c3a9c347SDiana Picus     OperandsMapping =
416c3a9c347SDiana Picus         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr,
417069da27fSDiana Picus                             FPRValueMapping, FPRValueMapping});
418c3a9c347SDiana Picus     break;
419c3a9c347SDiana Picus   }
4200b4190a9SDiana Picus   case G_MERGE_VALUES: {
4210b4190a9SDiana Picus     // We only support G_MERGE_VALUES for creating a double precision floating
4220b4190a9SDiana Picus     // point value out of two GPRs.
4236860a60cSDiana Picus     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
424a93803b9SDiana Picus     LLT Ty1 = MRI.getType(MI.getOperand(1).getReg());
4250b4190a9SDiana Picus     LLT Ty2 = MRI.getType(MI.getOperand(2).getReg());
426a93803b9SDiana Picus     if (Ty.getSizeInBits() != 64 || Ty1.getSizeInBits() != 32 ||
427a93803b9SDiana Picus         Ty2.getSizeInBits() != 32)
428245994d9SQuentin Colombet       return getInvalidInstructionMapping();
429a93803b9SDiana Picus     OperandsMapping =
43038699dbaSDiana Picus         getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
4310b4190a9SDiana Picus                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
4320b4190a9SDiana Picus                             &ARM::ValueMappings[ARM::GPR3OpsIdx]});
433a93803b9SDiana Picus     break;
434a93803b9SDiana Picus   }
4350b4190a9SDiana Picus   case G_UNMERGE_VALUES: {
4360b4190a9SDiana Picus     // We only support G_UNMERGE_VALUES for splitting a double precision
4370b4190a9SDiana Picus     // floating point value into two GPRs.
4386860a60cSDiana Picus     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
439a93803b9SDiana Picus     LLT Ty1 = MRI.getType(MI.getOperand(1).getReg());
4400b4190a9SDiana Picus     LLT Ty2 = MRI.getType(MI.getOperand(2).getReg());
4410b4190a9SDiana Picus     if (Ty.getSizeInBits() != 32 || Ty1.getSizeInBits() != 32 ||
4420b4190a9SDiana Picus         Ty2.getSizeInBits() != 64)
443245994d9SQuentin Colombet       return getInvalidInstructionMapping();
4440b4190a9SDiana Picus     OperandsMapping =
4450b4190a9SDiana Picus         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
4460b4190a9SDiana Picus                             &ARM::ValueMappings[ARM::GPR3OpsIdx],
4470b4190a9SDiana Picus                             &ARM::ValueMappings[ARM::DPR3OpsIdx]});
448a93803b9SDiana Picus     break;
449a93803b9SDiana Picus   }
450c4521756SDiana Picus   case G_BR:
451c4521756SDiana Picus     OperandsMapping = getOperandsMapping({nullptr});
452c4521756SDiana Picus     break;
45387a70679SDiana Picus   case G_BRCOND:
45487a70679SDiana Picus     OperandsMapping =
45587a70679SDiana Picus         getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr});
45687a70679SDiana Picus     break;
457153c3887SDiana Picus   case DBG_VALUE: {
458153c3887SDiana Picus     SmallVector<const ValueMapping *, 4> OperandBanks(NumOperands);
45935314533SDiana Picus     const MachineOperand &MaybeReg = MI.getOperand(0);
46035314533SDiana Picus     if (MaybeReg.isReg() && MaybeReg.getReg()) {
46135314533SDiana Picus       unsigned Size = MRI.getType(MaybeReg.getReg()).getSizeInBits();
46235314533SDiana Picus       if (Size > 32 && Size != 64)
46335314533SDiana Picus         return getInvalidInstructionMapping();
46435314533SDiana Picus       OperandBanks[0] = Size == 64 ? &ARM::ValueMappings[ARM::DPR3OpsIdx]
46535314533SDiana Picus                                    : &ARM::ValueMappings[ARM::GPR3OpsIdx];
46635314533SDiana Picus     }
467153c3887SDiana Picus     OperandsMapping = getOperandsMapping(OperandBanks);
468153c3887SDiana Picus     break;
469153c3887SDiana Picus   }
470519807f7SDiana Picus   default:
471245994d9SQuentin Colombet     return getInvalidInstructionMapping();
472812caee6SDiana Picus   }
473812caee6SDiana Picus 
4749b32faa8SDiana Picus #ifndef NDEBUG
4759b32faa8SDiana Picus   for (unsigned i = 0; i < NumOperands; i++) {
4769b32faa8SDiana Picus     for (const auto &Mapping : OperandsMapping[i]) {
4779b32faa8SDiana Picus       assert(
4789b32faa8SDiana Picus           (Mapping.RegBank->getID() != ARM::FPRRegBankID ||
479760df47bSSimon Tatham            MF.getSubtarget<ARMSubtarget>().hasVFP2Base()) &&
4809b32faa8SDiana Picus           "Trying to use floating point register bank on target without vfp");
4819b32faa8SDiana Picus     }
4829b32faa8SDiana Picus   }
4839b32faa8SDiana Picus #endif
4849b32faa8SDiana Picus 
485245994d9SQuentin Colombet   return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
486245994d9SQuentin Colombet                                NumOperands);
487812caee6SDiana Picus }
488