1 //===- MipsRegisterBankInfo.cpp ---------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements the targeting of the RegisterBankInfo class for Mips. 10 /// \todo This should be generated by TableGen. 11 //===----------------------------------------------------------------------===// 12 13 #include "MipsInstrInfo.h" 14 #include "MipsRegisterBankInfo.h" 15 #include "llvm/CodeGen/MachineRegisterInfo.h" 16 17 #define GET_TARGET_REGBANK_IMPL 18 19 #define DEBUG_TYPE "registerbankinfo" 20 21 #include "MipsGenRegisterBank.inc" 22 23 namespace llvm { 24 namespace Mips { 25 enum PartialMappingIdx { 26 PMI_GPR, 27 PMI_SPR, 28 PMI_DPR, 29 PMI_Min = PMI_GPR, 30 }; 31 32 RegisterBankInfo::PartialMapping PartMappings[]{ 33 {0, 32, GPRBRegBank}, 34 {0, 32, FPRBRegBank}, 35 {0, 64, FPRBRegBank} 36 }; 37 38 enum ValueMappingIdx { 39 InvalidIdx = 0, 40 GPRIdx = 1, 41 SPRIdx = 4, 42 DPRIdx = 7 43 }; 44 45 RegisterBankInfo::ValueMapping ValueMappings[] = { 46 // invalid 47 {nullptr, 0}, 48 // up to 3 operands in GPRs 49 {&PartMappings[PMI_GPR - PMI_Min], 1}, 50 {&PartMappings[PMI_GPR - PMI_Min], 1}, 51 {&PartMappings[PMI_GPR - PMI_Min], 1}, 52 // up to 3 ops operands FPRs - single precission 53 {&PartMappings[PMI_SPR - PMI_Min], 1}, 54 {&PartMappings[PMI_SPR - PMI_Min], 1}, 55 {&PartMappings[PMI_SPR - PMI_Min], 1}, 56 // up to 3 ops operands FPRs - double precission 57 {&PartMappings[PMI_DPR - PMI_Min], 1}, 58 {&PartMappings[PMI_DPR - PMI_Min], 1}, 59 {&PartMappings[PMI_DPR - PMI_Min], 1} 60 }; 61 62 } // end namespace Mips 63 } // end namespace llvm 64 65 using namespace llvm; 66 67 MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) 68 : MipsGenRegisterBankInfo() {} 69 70 const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass( 71 const TargetRegisterClass &RC) const { 72 using namespace Mips; 73 74 switch (RC.getID()) { 75 case Mips::GPR32RegClassID: 76 case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID: 77 case Mips::GPRMM16MovePPairFirstRegClassID: 78 case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID: 79 case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: 80 case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: 81 case Mips::SP32RegClassID: 82 return getRegBank(Mips::GPRBRegBankID); 83 case Mips::FGRCCRegClassID: 84 case Mips::FGR64RegClassID: 85 case Mips::AFGR64RegClassID: 86 return getRegBank(Mips::FPRBRegBankID); 87 default: 88 llvm_unreachable("Register class not supported"); 89 } 90 } 91 92 const RegisterBankInfo::InstructionMapping & 93 MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 94 95 unsigned Opc = MI.getOpcode(); 96 const MachineFunction &MF = *MI.getParent()->getParent(); 97 const MachineRegisterInfo &MRI = MF.getRegInfo(); 98 99 const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); 100 if (Mapping.isValid()) 101 return Mapping; 102 103 using namespace TargetOpcode; 104 105 unsigned NumOperands = MI.getNumOperands(); 106 const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 107 108 switch (Opc) { 109 case G_TRUNC: 110 case G_ADD: 111 case G_SUB: 112 case G_MUL: 113 case G_UMULH: 114 case G_LOAD: 115 case G_STORE: 116 case G_ZEXTLOAD: 117 case G_SEXTLOAD: 118 case G_GEP: 119 case G_AND: 120 case G_OR: 121 case G_XOR: 122 case G_SHL: 123 case G_ASHR: 124 case G_LSHR: 125 case G_SDIV: 126 case G_UDIV: 127 case G_SREM: 128 case G_UREM: 129 OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 130 break; 131 case G_FCONSTANT: { 132 LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 133 unsigned Size = Ty.getSizeInBits(); 134 const RegisterBankInfo::ValueMapping *FPRValueMapping = 135 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 136 : &Mips::ValueMappings[Mips::DPRIdx]; 137 OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr}); 138 break; 139 } 140 case G_CONSTANT: 141 case G_FRAME_INDEX: 142 case G_GLOBAL_VALUE: 143 case G_BRCOND: 144 OperandsMapping = 145 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 146 break; 147 case G_ICMP: 148 OperandsMapping = 149 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 150 &Mips::ValueMappings[Mips::GPRIdx], 151 &Mips::ValueMappings[Mips::GPRIdx]}); 152 break; 153 case G_SELECT: 154 OperandsMapping = 155 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 156 &Mips::ValueMappings[Mips::GPRIdx], 157 &Mips::ValueMappings[Mips::GPRIdx], 158 &Mips::ValueMappings[Mips::GPRIdx]}); 159 break; 160 default: 161 return getInvalidInstructionMapping(); 162 } 163 164 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping, 165 NumOperands); 166 } 167