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 case Mips::GP32RegClassID: 83 return getRegBank(Mips::GPRBRegBankID); 84 case Mips::FGRCCRegClassID: 85 case Mips::FGR32RegClassID: 86 case Mips::FGR64RegClassID: 87 case Mips::AFGR64RegClassID: 88 return getRegBank(Mips::FPRBRegBankID); 89 default: 90 llvm_unreachable("Register class not supported"); 91 } 92 } 93 94 const RegisterBankInfo::InstructionMapping & 95 MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 96 97 unsigned Opc = MI.getOpcode(); 98 const MachineFunction &MF = *MI.getParent()->getParent(); 99 const MachineRegisterInfo &MRI = MF.getRegInfo(); 100 101 const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); 102 if (Mapping.isValid()) 103 return Mapping; 104 105 using namespace TargetOpcode; 106 107 unsigned NumOperands = MI.getNumOperands(); 108 const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 109 110 switch (Opc) { 111 case G_TRUNC: 112 case G_ADD: 113 case G_SUB: 114 case G_MUL: 115 case G_UMULH: 116 case G_LOAD: 117 case G_STORE: 118 case G_ZEXTLOAD: 119 case G_SEXTLOAD: 120 case G_GEP: 121 case G_AND: 122 case G_OR: 123 case G_XOR: 124 case G_SHL: 125 case G_ASHR: 126 case G_LSHR: 127 case G_SDIV: 128 case G_UDIV: 129 case G_SREM: 130 case G_UREM: 131 OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 132 break; 133 case G_FADD: 134 case G_FSUB: 135 case G_FMUL: 136 case G_FDIV: 137 case G_FABS: { 138 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 139 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 140 OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 141 : &Mips::ValueMappings[Mips::DPRIdx]; 142 break; 143 } 144 case G_FCONSTANT: { 145 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 146 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 147 const RegisterBankInfo::ValueMapping *FPRValueMapping = 148 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 149 : &Mips::ValueMappings[Mips::DPRIdx]; 150 OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr}); 151 break; 152 } 153 case G_FCMP: { 154 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 155 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 156 const RegisterBankInfo::ValueMapping *FPRValueMapping = 157 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 158 : &Mips::ValueMappings[Mips::DPRIdx]; 159 OperandsMapping = 160 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 161 FPRValueMapping, FPRValueMapping}); 162 break; 163 } 164 case G_FPEXT: 165 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 166 &Mips::ValueMappings[Mips::SPRIdx]}); 167 break; 168 case G_FPTRUNC: 169 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx], 170 &Mips::ValueMappings[Mips::DPRIdx]}); 171 break; 172 case G_CONSTANT: 173 case G_FRAME_INDEX: 174 case G_GLOBAL_VALUE: 175 case G_BRCOND: 176 OperandsMapping = 177 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 178 break; 179 case G_ICMP: 180 OperandsMapping = 181 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 182 &Mips::ValueMappings[Mips::GPRIdx], 183 &Mips::ValueMappings[Mips::GPRIdx]}); 184 break; 185 case G_SELECT: 186 OperandsMapping = 187 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 188 &Mips::ValueMappings[Mips::GPRIdx], 189 &Mips::ValueMappings[Mips::GPRIdx], 190 &Mips::ValueMappings[Mips::GPRIdx]}); 191 break; 192 default: 193 return getInvalidInstructionMapping(); 194 } 195 196 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping, 197 NumOperands); 198 } 199