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 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 138 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 139 OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 140 : &Mips::ValueMappings[Mips::DPRIdx]; 141 break; 142 } 143 case G_FCONSTANT: { 144 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 145 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 146 const RegisterBankInfo::ValueMapping *FPRValueMapping = 147 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 148 : &Mips::ValueMappings[Mips::DPRIdx]; 149 OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr}); 150 break; 151 } 152 case G_FCMP: { 153 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 154 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 155 const RegisterBankInfo::ValueMapping *FPRValueMapping = 156 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 157 : &Mips::ValueMappings[Mips::DPRIdx]; 158 OperandsMapping = 159 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 160 FPRValueMapping, FPRValueMapping}); 161 break; 162 } 163 case G_CONSTANT: 164 case G_FRAME_INDEX: 165 case G_GLOBAL_VALUE: 166 case G_BRCOND: 167 OperandsMapping = 168 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 169 break; 170 case G_ICMP: 171 OperandsMapping = 172 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 173 &Mips::ValueMappings[Mips::GPRIdx], 174 &Mips::ValueMappings[Mips::GPRIdx]}); 175 break; 176 case G_SELECT: 177 OperandsMapping = 178 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 179 &Mips::ValueMappings[Mips::GPRIdx], 180 &Mips::ValueMappings[Mips::GPRIdx], 181 &Mips::ValueMappings[Mips::GPRIdx]}); 182 break; 183 default: 184 return getInvalidInstructionMapping(); 185 } 186 187 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping, 188 NumOperands); 189 } 190