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