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