1 //===- ARMRegisterBankInfo.cpp -----------------------------------*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file implements the targeting of the RegisterBankInfo class for ARM.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
14 #include "ARMRegisterBankInfo.h"
15 #include "ARMInstrInfo.h" // For the register classes
16 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
17 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/Target/TargetRegisterInfo.h"
23 #ifndef LLVM_BUILD_GLOBAL_ISEL
24 #error "You shouldn't build this"
27 // FIXME: TableGen this.
28 // If it grows too much and TableGen still isn't ready to do the job, extract it
29 // into an ARMGenRegisterBankInfo.def (similar to AArch64).
32 RegisterBank GPRRegBank;
33 RegisterBank *RegBanks[] = {&GPRRegBank};
35 RegisterBankInfo::PartialMapping GPRPartialMapping{0, 32, GPRRegBank};
37 RegisterBankInfo::ValueMapping ValueMappings[] = {
38 {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1}};
39 } // end namespace arm
40 } // end namespace llvm
42 ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI)
43 : RegisterBankInfo(ARM::RegBanks, ARM::NumRegisterBanks) {
44 static bool AlreadyInit = false;
45 // We have only one set of register banks, whatever the subtarget
46 // is. Therefore, the initialization of the RegBanks table should be
47 // done only once. Indeed the table of all register banks
48 // (ARM::RegBanks) is unique in the compiler. At some point, it
49 // will get tablegen'ed and the whole constructor becomes empty.
54 // Initialize the GPR bank.
55 createRegisterBank(ARM::GPRRegBankID, "GPRB");
57 addRegBankCoverage(ARM::GPRRegBankID, ARM::GPRRegClassID, TRI);
58 addRegBankCoverage(ARM::GPRRegBankID, ARM::GPRwithAPSRRegClassID, TRI);
59 const RegisterBank &RBGPR = getRegBank(ARM::GPRRegBankID);
61 assert(&ARM::GPRRegBank == &RBGPR && "The order in RegBanks is messed up");
62 assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRRegClassID)) &&
63 "Subclass not added?");
64 assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRwithAPSRRegClassID)) &&
65 "Subclass not added?");
66 assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnopcRegClassID)) &&
67 "Subclass not added?");
68 assert(RBGPR.covers(*TRI.getRegClass(ARM::rGPRRegClassID)) &&
69 "Subclass not added?");
70 assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPRRegClassID)) &&
71 "Subclass not added?");
72 assert(RBGPR.covers(*TRI.getRegClass(ARM::tcGPRRegClassID)) &&
73 "Subclass not added?");
74 assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPR_and_tcGPRRegClassID)) &&
75 "Subclass not added?");
76 assert(RBGPR.getSize() == 32 && "GPRs should hold up to 32-bit");
79 const RegisterBank &ARMRegisterBankInfo::getRegBankFromRegClass(
80 const TargetRegisterClass &RC) const {
85 case tGPR_and_tcGPRRegClassID:
86 return getRegBank(ARM::GPRRegBankID);
88 llvm_unreachable("Unsupported register kind");
91 llvm_unreachable("Switch should handle all register classes");
94 RegisterBankInfo::InstructionMapping
95 ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
96 auto Opc = MI.getOpcode();
98 // Try the default logic for non-generic instructions that are either copies
99 // or already have some operands assigned to banks.
100 if (!isPreISelGenericOpcode(Opc)) {
101 InstructionMapping Mapping = getInstrMappingImpl(MI);
102 if (Mapping.isValid())
106 using namespace TargetOpcode;
108 unsigned NumOperands = MI.getNumOperands();
109 const ValueMapping *OperandsMapping = &ARM::ValueMappings[0];
114 // FIXME: We're abusing the fact that everything lives in a GPR for now; in
115 // the real world we would use different mappings.
116 OperandsMapping = &ARM::ValueMappings[0];
119 OperandsMapping = getOperandsMapping({&ARM::ValueMappings[0], nullptr});
122 return InstructionMapping{};
125 return InstructionMapping{DefaultMappingID, /*Cost=*/1, OperandsMapping,