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 } 128