]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
Merge ^/head r311546 through r311683.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARM / ARMRegisterBankInfo.cpp
1 //===- ARMRegisterBankInfo.cpp -----------------------------------*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file implements the targeting of the RegisterBankInfo class for ARM.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13
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"
20
21 using namespace llvm;
22
23 #ifndef LLVM_BUILD_GLOBAL_ISEL
24 #error "You shouldn't build this"
25 #endif
26
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).
30 namespace llvm {
31 namespace ARM {
32 RegisterBank GPRRegBank;
33 RegisterBank *RegBanks[] = {&GPRRegBank};
34
35 RegisterBankInfo::PartialMapping GPRPartialMapping{0, 32, GPRRegBank};
36
37 RegisterBankInfo::ValueMapping ValueMappings[] = {
38     {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1}};
39 } // end namespace arm
40 } // end namespace llvm
41
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.
50   if (AlreadyInit)
51     return;
52   AlreadyInit = true;
53
54   // Initialize the GPR bank.
55   createRegisterBank(ARM::GPRRegBankID, "GPRB");
56
57   addRegBankCoverage(ARM::GPRRegBankID, ARM::GPRRegClassID, TRI);
58   addRegBankCoverage(ARM::GPRRegBankID, ARM::GPRwithAPSRRegClassID, TRI);
59   const RegisterBank &RBGPR = getRegBank(ARM::GPRRegBankID);
60   (void)RBGPR;
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");
77 }
78
79 const RegisterBank &ARMRegisterBankInfo::getRegBankFromRegClass(
80     const TargetRegisterClass &RC) const {
81   using namespace ARM;
82
83   switch (RC.getID()) {
84   case GPRRegClassID:
85   case tGPR_and_tcGPRRegClassID:
86     return getRegBank(ARM::GPRRegBankID);
87   default:
88     llvm_unreachable("Unsupported register kind");
89   }
90
91   llvm_unreachable("Switch should handle all register classes");
92 }
93
94 RegisterBankInfo::InstructionMapping
95 ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
96   auto Opc = MI.getOpcode();
97
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())
103       return Mapping;
104   }
105
106   using namespace TargetOpcode;
107
108   unsigned NumOperands = MI.getNumOperands();
109   const ValueMapping *OperandsMapping = &ARM::ValueMappings[0];
110
111   switch (Opc) {
112   case G_ADD:
113   case G_LOAD:
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];
117     break;
118   case G_FRAME_INDEX:
119     OperandsMapping = getOperandsMapping({&ARM::ValueMappings[0], nullptr});
120     break;
121   default:
122     return InstructionMapping{};
123   }
124
125   return InstructionMapping{DefaultMappingID, /*Cost=*/1, OperandsMapping,
126                             NumOperands};
127 }