MipsSEInstrInfo.cpp revision a6c3a4ee76ef8464d3c83472e15af521ade7eeb4
1cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org//===-- MipsSEInstrInfo.cpp - Mips32/64 Instruction Information -----------===// 2cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org// 3cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org// The LLVM Compiler Infrastructure 4cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org// 5cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org// This file is distributed under the University of Illinois Open Source 6cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org// License. See LICENSE.TXT for details. 7cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org// 8cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org//===----------------------------------------------------------------------===// 9cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org// 10cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org// This file contains the Mips32/64 implementation of the TargetInstrInfo class. 11cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org// 12cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org//===----------------------------------------------------------------------===// 13cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 14bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org#include "MipsSEInstrInfo.h" 15bc25dfc798fff225ce65355ecda19d2b85bd0e74commit-bot@chromium.org#include "InstPrinter/MipsInstPrinter.h" 16cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include "MipsMachineFunction.h" 170f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#include "MipsTargetMachine.h" 18cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include "llvm/ADT/STLExtras.h" 19cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include "llvm/CodeGen/MachineInstrBuilder.h" 20cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include "llvm/CodeGen/MachineRegisterInfo.h" 218b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "llvm/Support/CommandLine.h" 22cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include "llvm/Support/ErrorHandling.h" 23cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org#include "llvm/Support/TargetRegistry.h" 24cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 25cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.orgusing namespace llvm; 26cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org 27cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.orgstatic cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false), 28cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org cl::desc("Expand double precision loads and " 29d611864e679a58865b111e74fe7ac919cba42163commit-bot@chromium.org "stores to their single precision " 30d611864e679a58865b111e74fe7ac919cba42163commit-bot@chromium.org "counterparts.")); 31d611864e679a58865b111e74fe7ac919cba42163commit-bot@chromium.org 32d611864e679a58865b111e74fe7ac919cba42163commit-bot@chromium.orgMipsSEInstrInfo::MipsSEInstrInfo(MipsTargetMachine &tm) 33d611864e679a58865b111e74fe7ac919cba42163commit-bot@chromium.org : MipsInstrInfo(tm, 34d611864e679a58865b111e74fe7ac919cba42163commit-bot@chromium.org tm.getRelocationModel() == Reloc::PIC_ ? Mips::B : Mips::J), 35cd7992ba55e8b87580f54e7c19fc033bed01640dcommit-bot@chromium.org RI(*tm.getSubtargetImpl()), 36 IsN64(tm.getSubtarget<MipsSubtarget>().isABI_N64()) {} 37 38const MipsRegisterInfo &MipsSEInstrInfo::getRegisterInfo() const { 39 return RI; 40} 41 42/// isLoadFromStackSlot - If the specified machine instruction is a direct 43/// load from a stack slot, return the virtual or physical register number of 44/// the destination along with the FrameIndex of the loaded stack slot. If 45/// not, return 0. This predicate must return 0 if the instruction has 46/// any side effects other than loading from the stack slot. 47unsigned MipsSEInstrInfo:: 48isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const 49{ 50 unsigned Opc = MI->getOpcode(); 51 52 if ((Opc == Mips::LW) || (Opc == Mips::LD) || 53 (Opc == Mips::LWC1) || (Opc == Mips::LDC1) || (Opc == Mips::LDC164)) { 54 if ((MI->getOperand(1).isFI()) && // is a stack slot 55 (MI->getOperand(2).isImm()) && // the imm is zero 56 (isZeroImm(MI->getOperand(2)))) { 57 FrameIndex = MI->getOperand(1).getIndex(); 58 return MI->getOperand(0).getReg(); 59 } 60 } 61 62 return 0; 63} 64 65/// isStoreToStackSlot - If the specified machine instruction is a direct 66/// store to a stack slot, return the virtual or physical register number of 67/// the source reg along with the FrameIndex of the loaded stack slot. If 68/// not, return 0. This predicate must return 0 if the instruction has 69/// any side effects other than storing to the stack slot. 70unsigned MipsSEInstrInfo:: 71isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const 72{ 73 unsigned Opc = MI->getOpcode(); 74 75 if ((Opc == Mips::SW) || (Opc == Mips::SD) || 76 (Opc == Mips::SWC1) || (Opc == Mips::SDC1) || (Opc == Mips::SDC164)) { 77 if ((MI->getOperand(1).isFI()) && // is a stack slot 78 (MI->getOperand(2).isImm()) && // the imm is zero 79 (isZeroImm(MI->getOperand(2)))) { 80 FrameIndex = MI->getOperand(1).getIndex(); 81 return MI->getOperand(0).getReg(); 82 } 83 } 84 return 0; 85} 86 87void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 88 MachineBasicBlock::iterator I, DebugLoc DL, 89 unsigned DestReg, unsigned SrcReg, 90 bool KillSrc) const { 91 unsigned Opc = 0, ZeroReg = 0; 92 93 if (Mips::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg. 94 if (Mips::GPR32RegClass.contains(SrcReg)) 95 Opc = Mips::ADDu, ZeroReg = Mips::ZERO; 96 else if (Mips::CCRRegClass.contains(SrcReg)) 97 Opc = Mips::CFC1; 98 else if (Mips::FGR32RegClass.contains(SrcReg)) 99 Opc = Mips::MFC1; 100 else if (Mips::HI32RegClass.contains(SrcReg)) 101 Opc = Mips::MFHI, SrcReg = 0; 102 else if (Mips::LO32RegClass.contains(SrcReg)) 103 Opc = Mips::MFLO, SrcReg = 0; 104 else if (Mips::HI32DSPRegClass.contains(SrcReg)) 105 Opc = Mips::MFHI_DSP; 106 else if (Mips::LO32DSPRegClass.contains(SrcReg)) 107 Opc = Mips::MFLO_DSP; 108 else if (Mips::DSPCCRegClass.contains(SrcReg)) { 109 BuildMI(MBB, I, DL, get(Mips::RDDSP), DestReg).addImm(1 << 4) 110 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); 111 return; 112 } 113 else if (Mips::MSACtrlRegClass.contains(SrcReg)) 114 Opc = Mips::CFCMSA; 115 } 116 else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg. 117 if (Mips::CCRRegClass.contains(DestReg)) 118 Opc = Mips::CTC1; 119 else if (Mips::FGR32RegClass.contains(DestReg)) 120 Opc = Mips::MTC1; 121 else if (Mips::HI32RegClass.contains(DestReg)) 122 Opc = Mips::MTHI, DestReg = 0; 123 else if (Mips::LO32RegClass.contains(DestReg)) 124 Opc = Mips::MTLO, DestReg = 0; 125 else if (Mips::HI32DSPRegClass.contains(DestReg)) 126 Opc = Mips::MTHI_DSP; 127 else if (Mips::LO32DSPRegClass.contains(DestReg)) 128 Opc = Mips::MTLO_DSP; 129 else if (Mips::DSPCCRegClass.contains(DestReg)) { 130 BuildMI(MBB, I, DL, get(Mips::WRDSP)) 131 .addReg(SrcReg, getKillRegState(KillSrc)).addImm(1 << 4) 132 .addReg(DestReg, RegState::ImplicitDefine); 133 return; 134 } 135 else if (Mips::MSACtrlRegClass.contains(DestReg)) 136 Opc = Mips::CTCMSA; 137 } 138 else if (Mips::FGR32RegClass.contains(DestReg, SrcReg)) 139 Opc = Mips::FMOV_S; 140 else if (Mips::AFGR64RegClass.contains(DestReg, SrcReg)) 141 Opc = Mips::FMOV_D32; 142 else if (Mips::FGR64RegClass.contains(DestReg, SrcReg)) 143 Opc = Mips::FMOV_D64; 144 else if (Mips::GPR64RegClass.contains(DestReg)) { // Copy to CPU64 Reg. 145 if (Mips::GPR64RegClass.contains(SrcReg)) 146 Opc = Mips::DADDu, ZeroReg = Mips::ZERO_64; 147 else if (Mips::HI64RegClass.contains(SrcReg)) 148 Opc = Mips::MFHI64, SrcReg = 0; 149 else if (Mips::LO64RegClass.contains(SrcReg)) 150 Opc = Mips::MFLO64, SrcReg = 0; 151 else if (Mips::FGR64RegClass.contains(SrcReg)) 152 Opc = Mips::DMFC1; 153 } 154 else if (Mips::GPR64RegClass.contains(SrcReg)) { // Copy from CPU64 Reg. 155 if (Mips::HI64RegClass.contains(DestReg)) 156 Opc = Mips::MTHI64, DestReg = 0; 157 else if (Mips::LO64RegClass.contains(DestReg)) 158 Opc = Mips::MTLO64, DestReg = 0; 159 else if (Mips::FGR64RegClass.contains(DestReg)) 160 Opc = Mips::DMTC1; 161 } 162 163 assert(Opc && "Cannot copy registers"); 164 165 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); 166 167 if (DestReg) 168 MIB.addReg(DestReg, RegState::Define); 169 170 if (SrcReg) 171 MIB.addReg(SrcReg, getKillRegState(KillSrc)); 172 173 if (ZeroReg) 174 MIB.addReg(ZeroReg); 175} 176 177void MipsSEInstrInfo:: 178storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 179 unsigned SrcReg, bool isKill, int FI, 180 const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, 181 int64_t Offset) const { 182 DebugLoc DL; 183 if (I != MBB.end()) DL = I->getDebugLoc(); 184 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); 185 186 unsigned Opc = 0; 187 188 if (Mips::GPR32RegClass.hasSubClassEq(RC)) 189 Opc = Mips::SW; 190 else if (Mips::GPR64RegClass.hasSubClassEq(RC)) 191 Opc = Mips::SD; 192 else if (Mips::ACC64RegClass.hasSubClassEq(RC)) 193 Opc = Mips::STORE_ACC64; 194 else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC)) 195 Opc = Mips::STORE_ACC64DSP; 196 else if (Mips::ACC128RegClass.hasSubClassEq(RC)) 197 Opc = Mips::STORE_ACC128; 198 else if (Mips::DSPCCRegClass.hasSubClassEq(RC)) 199 Opc = Mips::STORE_CCOND_DSP; 200 else if (Mips::FGR32RegClass.hasSubClassEq(RC)) 201 Opc = Mips::SWC1; 202 else if (Mips::AFGR64RegClass.hasSubClassEq(RC)) 203 Opc = Mips::SDC1; 204 else if (Mips::FGR64RegClass.hasSubClassEq(RC)) 205 Opc = Mips::SDC164; 206 else if (RC->hasType(MVT::v16i8)) 207 Opc = Mips::ST_B; 208 else if (RC->hasType(MVT::v8i16) || RC->hasType(MVT::v8f16)) 209 Opc = Mips::ST_H; 210 else if (RC->hasType(MVT::v4i32) || RC->hasType(MVT::v4f32)) 211 Opc = Mips::ST_W; 212 else if (RC->hasType(MVT::v2i64) || RC->hasType(MVT::v2f64)) 213 Opc = Mips::ST_D; 214 215 assert(Opc && "Register class not handled!"); 216 BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)) 217 .addFrameIndex(FI).addImm(Offset).addMemOperand(MMO); 218} 219 220void MipsSEInstrInfo:: 221loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 222 unsigned DestReg, int FI, const TargetRegisterClass *RC, 223 const TargetRegisterInfo *TRI, int64_t Offset) const { 224 DebugLoc DL; 225 if (I != MBB.end()) DL = I->getDebugLoc(); 226 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); 227 unsigned Opc = 0; 228 229 if (Mips::GPR32RegClass.hasSubClassEq(RC)) 230 Opc = Mips::LW; 231 else if (Mips::GPR64RegClass.hasSubClassEq(RC)) 232 Opc = Mips::LD; 233 else if (Mips::ACC64RegClass.hasSubClassEq(RC)) 234 Opc = Mips::LOAD_ACC64; 235 else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC)) 236 Opc = Mips::LOAD_ACC64DSP; 237 else if (Mips::ACC128RegClass.hasSubClassEq(RC)) 238 Opc = Mips::LOAD_ACC128; 239 else if (Mips::DSPCCRegClass.hasSubClassEq(RC)) 240 Opc = Mips::LOAD_CCOND_DSP; 241 else if (Mips::FGR32RegClass.hasSubClassEq(RC)) 242 Opc = Mips::LWC1; 243 else if (Mips::AFGR64RegClass.hasSubClassEq(RC)) 244 Opc = Mips::LDC1; 245 else if (Mips::FGR64RegClass.hasSubClassEq(RC)) 246 Opc = Mips::LDC164; 247 else if (RC->hasType(MVT::v16i8)) 248 Opc = Mips::LD_B; 249 else if (RC->hasType(MVT::v8i16) || RC->hasType(MVT::v8f16)) 250 Opc = Mips::LD_H; 251 else if (RC->hasType(MVT::v4i32) || RC->hasType(MVT::v4f32)) 252 Opc = Mips::LD_W; 253 else if (RC->hasType(MVT::v2i64) || RC->hasType(MVT::v2f64)) 254 Opc = Mips::LD_D; 255 256 assert(Opc && "Register class not handled!"); 257 BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset) 258 .addMemOperand(MMO); 259} 260 261bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 262 MachineBasicBlock &MBB = *MI->getParent(); 263 264 switch(MI->getDesc().getOpcode()) { 265 default: 266 return false; 267 case Mips::RetRA: 268 expandRetRA(MBB, MI, Mips::RET); 269 break; 270 case Mips::PseudoCVT_S_W: 271 expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false); 272 break; 273 case Mips::PseudoCVT_D32_W: 274 expandCvtFPInt(MBB, MI, Mips::CVT_D32_W, Mips::MTC1, false); 275 break; 276 case Mips::PseudoCVT_S_L: 277 expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, true); 278 break; 279 case Mips::PseudoCVT_D64_W: 280 expandCvtFPInt(MBB, MI, Mips::CVT_D64_W, Mips::MTC1, true); 281 break; 282 case Mips::PseudoCVT_D64_L: 283 expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true); 284 break; 285 case Mips::BuildPairF64: 286 expandBuildPairF64(MBB, MI, false); 287 break; 288 case Mips::BuildPairF64_64: 289 expandBuildPairF64(MBB, MI, true); 290 break; 291 case Mips::ExtractElementF64: 292 expandExtractElementF64(MBB, MI, false); 293 break; 294 case Mips::ExtractElementF64_64: 295 expandExtractElementF64(MBB, MI, true); 296 break; 297 case Mips::PseudoLDC1: 298 expandDPLoadStore(MBB, MI, Mips::LDC1, Mips::LWC1); 299 break; 300 case Mips::PseudoSDC1: 301 expandDPLoadStore(MBB, MI, Mips::SDC1, Mips::SWC1); 302 break; 303 case Mips::MIPSeh_return32: 304 case Mips::MIPSeh_return64: 305 expandEhReturn(MBB, MI); 306 break; 307 } 308 309 MBB.erase(MI); 310 return true; 311} 312 313/// getOppositeBranchOpc - Return the inverse of the specified 314/// opcode, e.g. turning BEQ to BNE. 315unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const { 316 switch (Opc) { 317 default: llvm_unreachable("Illegal opcode!"); 318 case Mips::BEQ: return Mips::BNE; 319 case Mips::BNE: return Mips::BEQ; 320 case Mips::BGTZ: return Mips::BLEZ; 321 case Mips::BGEZ: return Mips::BLTZ; 322 case Mips::BLTZ: return Mips::BGEZ; 323 case Mips::BLEZ: return Mips::BGTZ; 324 case Mips::BEQ64: return Mips::BNE64; 325 case Mips::BNE64: return Mips::BEQ64; 326 case Mips::BGTZ64: return Mips::BLEZ64; 327 case Mips::BGEZ64: return Mips::BLTZ64; 328 case Mips::BLTZ64: return Mips::BGEZ64; 329 case Mips::BLEZ64: return Mips::BGTZ64; 330 case Mips::BC1T: return Mips::BC1F; 331 case Mips::BC1F: return Mips::BC1T; 332 } 333} 334 335/// Adjust SP by Amount bytes. 336void MipsSEInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, 337 MachineBasicBlock &MBB, 338 MachineBasicBlock::iterator I) const { 339 const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>(); 340 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 341 unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 342 unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; 343 344 if (isInt<16>(Amount))// addi sp, sp, amount 345 BuildMI(MBB, I, DL, get(ADDiu), SP).addReg(SP).addImm(Amount); 346 else { // Expand immediate that doesn't fit in 16-bit. 347 unsigned Reg = loadImmediate(Amount, MBB, I, DL, 0); 348 BuildMI(MBB, I, DL, get(ADDu), SP).addReg(SP).addReg(Reg, RegState::Kill); 349 } 350} 351 352/// This function generates the sequence of instructions needed to get the 353/// result of adding register REG and immediate IMM. 354unsigned 355MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB, 356 MachineBasicBlock::iterator II, DebugLoc DL, 357 unsigned *NewImm) const { 358 MipsAnalyzeImmediate AnalyzeImm; 359 const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>(); 360 MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); 361 unsigned Size = STI.isABI_N64() ? 64 : 32; 362 unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi; 363 unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 364 const TargetRegisterClass *RC = STI.isABI_N64() ? 365 &Mips::GPR64RegClass : &Mips::GPR32RegClass; 366 bool LastInstrIsADDiu = NewImm; 367 368 const MipsAnalyzeImmediate::InstSeq &Seq = 369 AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu); 370 MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); 371 372 assert(Seq.size() && (!LastInstrIsADDiu || (Seq.size() > 1))); 373 374 // The first instruction can be a LUi, which is different from other 375 // instructions (ADDiu, ORI and SLL) in that it does not have a register 376 // operand. 377 unsigned Reg = RegInfo.createVirtualRegister(RC); 378 379 if (Inst->Opc == LUi) 380 BuildMI(MBB, II, DL, get(LUi), Reg).addImm(SignExtend64<16>(Inst->ImmOpnd)); 381 else 382 BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(ZEROReg) 383 .addImm(SignExtend64<16>(Inst->ImmOpnd)); 384 385 // Build the remaining instructions in Seq. 386 for (++Inst; Inst != Seq.end() - LastInstrIsADDiu; ++Inst) 387 BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(Reg, RegState::Kill) 388 .addImm(SignExtend64<16>(Inst->ImmOpnd)); 389 390 if (LastInstrIsADDiu) 391 *NewImm = Inst->ImmOpnd; 392 393 return Reg; 394} 395 396unsigned MipsSEInstrInfo::getAnalyzableBrOpc(unsigned Opc) const { 397 return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ || 398 Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ || 399 Opc == Mips::BEQ64 || Opc == Mips::BNE64 || Opc == Mips::BGTZ64 || 400 Opc == Mips::BGEZ64 || Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 || 401 Opc == Mips::BC1T || Opc == Mips::BC1F || Opc == Mips::B || 402 Opc == Mips::J) ? 403 Opc : 0; 404} 405 406void MipsSEInstrInfo::expandRetRA(MachineBasicBlock &MBB, 407 MachineBasicBlock::iterator I, 408 unsigned Opc) const { 409 BuildMI(MBB, I, I->getDebugLoc(), get(Opc)).addReg(Mips::RA); 410} 411 412std::pair<bool, bool> 413MipsSEInstrInfo::compareOpndSize(unsigned Opc, 414 const MachineFunction &MF) const { 415 const MCInstrDesc &Desc = get(Opc); 416 assert(Desc.NumOperands == 2 && "Unary instruction expected."); 417 const MipsRegisterInfo *RI = &getRegisterInfo(); 418 unsigned DstRegSize = getRegClass(Desc, 0, RI, MF)->getSize(); 419 unsigned SrcRegSize = getRegClass(Desc, 1, RI, MF)->getSize(); 420 421 return std::make_pair(DstRegSize > SrcRegSize, DstRegSize < SrcRegSize); 422} 423 424void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB, 425 MachineBasicBlock::iterator I, 426 unsigned CvtOpc, unsigned MovOpc, 427 bool IsI64) const { 428 const MCInstrDesc &CvtDesc = get(CvtOpc), &MovDesc = get(MovOpc); 429 const MachineOperand &Dst = I->getOperand(0), &Src = I->getOperand(1); 430 unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg; 431 unsigned KillSrc = getKillRegState(Src.isKill()); 432 DebugLoc DL = I->getDebugLoc(); 433 bool DstIsLarger, SrcIsLarger; 434 435 tie(DstIsLarger, SrcIsLarger) = compareOpndSize(CvtOpc, *MBB.getParent()); 436 437 if (DstIsLarger) 438 TmpReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo); 439 440 if (SrcIsLarger) 441 DstReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo); 442 443 BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc); 444 BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill); 445} 446 447void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB, 448 MachineBasicBlock::iterator I, 449 bool FP64) const { 450 unsigned DstReg = I->getOperand(0).getReg(); 451 unsigned SrcReg = I->getOperand(1).getReg(); 452 unsigned N = I->getOperand(2).getImm(); 453 DebugLoc dl = I->getDebugLoc(); 454 455 assert(N < 2 && "Invalid immediate"); 456 unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo; 457 unsigned SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx); 458 459 if (SubIdx == Mips::sub_hi && FP64) 460 BuildMI(MBB, I, dl, get(Mips::MFHC1), DstReg).addReg(SubReg); 461 else 462 BuildMI(MBB, I, dl, get(Mips::MFC1), DstReg).addReg(SubReg); 463} 464 465void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB, 466 MachineBasicBlock::iterator I, 467 bool FP64) const { 468 unsigned DstReg = I->getOperand(0).getReg(); 469 unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg(); 470 const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1); 471 DebugLoc dl = I->getDebugLoc(); 472 const TargetRegisterInfo &TRI = getRegisterInfo(); 473 474 // mtc1 Lo, $fp 475 // mtc1 Hi, $fp + 1 476 BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo)) 477 .addReg(LoReg); 478 479 if (FP64) 480 BuildMI(MBB, I, dl, get(Mips::MTHC1), TRI.getSubReg(DstReg, Mips::sub_hi)) 481 .addReg(HiReg); 482 else 483 BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi)) 484 .addReg(HiReg); 485} 486 487/// Add 4 to the displacement of operand MO. 488static void fixDisp(MachineOperand &MO) { 489 switch (MO.getType()) { 490 default: 491 llvm_unreachable("Unhandled operand type."); 492 case MachineOperand::MO_Immediate: 493 MO.setImm(MO.getImm() + 4); 494 break; 495 case MachineOperand::MO_GlobalAddress: 496 case MachineOperand::MO_ConstantPoolIndex: 497 case MachineOperand::MO_BlockAddress: 498 case MachineOperand::MO_TargetIndex: 499 case MachineOperand::MO_ExternalSymbol: 500 MO.setOffset(MO.getOffset() + 4); 501 break; 502 } 503} 504 505void MipsSEInstrInfo::expandDPLoadStore(MachineBasicBlock &MBB, 506 MachineBasicBlock::iterator I, 507 unsigned OpcD, unsigned OpcS) const { 508 // If NoDPLoadStore is false, just change the opcode. 509 if (!NoDPLoadStore) { 510 genInstrWithNewOpc(OpcD, I); 511 return; 512 } 513 514 // Expand a double precision FP load or store to two single precision 515 // instructions. 516 517 const TargetRegisterInfo &TRI = getRegisterInfo(); 518 const MachineOperand &ValReg = I->getOperand(0); 519 unsigned LoReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_lo); 520 unsigned HiReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_hi); 521 522 if (!TM.getSubtarget<MipsSubtarget>().isLittle()) 523 std::swap(LoReg, HiReg); 524 525 // Create an instruction which loads from or stores to the lower memory 526 // address. 527 MachineInstrBuilder MIB = genInstrWithNewOpc(OpcS, I); 528 MIB->getOperand(0).setReg(LoReg); 529 530 // Create an instruction which loads from or stores to the higher memory 531 // address. 532 MIB = genInstrWithNewOpc(OpcS, I); 533 MIB->getOperand(0).setReg(HiReg); 534 fixDisp(MIB->getOperand(2)); 535} 536 537void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB, 538 MachineBasicBlock::iterator I) const { 539 // This pseudo instruction is generated as part of the lowering of 540 // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and 541 // indirect jump to TargetReg 542 const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>(); 543 unsigned ADDU = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; 544 unsigned JR = STI.isABI_N64() ? Mips::JR64 : Mips::JR; 545 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; 546 unsigned RA = STI.isABI_N64() ? Mips::RA_64 : Mips::RA; 547 unsigned T9 = STI.isABI_N64() ? Mips::T9_64 : Mips::T9; 548 unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 549 unsigned OffsetReg = I->getOperand(0).getReg(); 550 unsigned TargetReg = I->getOperand(1).getReg(); 551 552 // addu $ra, $v0, $zero 553 // addu $sp, $sp, $v1 554 // jr $ra 555 if (TM.getRelocationModel() == Reloc::PIC_) 556 BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), T9) 557 .addReg(TargetReg).addReg(ZERO); 558 BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), RA) 559 .addReg(TargetReg).addReg(ZERO); 560 BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), SP) 561 .addReg(SP).addReg(OffsetReg); 562 BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(JR)).addReg(RA); 563} 564 565const MipsInstrInfo *llvm::createMipsSEInstrInfo(MipsTargetMachine &TM) { 566 return new MipsSEInstrInfo(TM); 567} 568