1 //===-- MipsSEInstrInfo.cpp - Mips32/64 Instruction Information -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the Mips32/64 implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MipsSEInstrInfo.h" 15 #include "MipsAnalyzeImmediate.h" 16 #include "InstPrinter/MipsInstPrinter.h" 17 #include "MipsMachineFunction.h" 18 #include "MipsTargetMachine.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/TargetRegistry.h" 25 26 using namespace llvm; 27 28 MipsSEInstrInfo::MipsSEInstrInfo(const MipsSubtarget &STI) 29 : MipsInstrInfo(STI, STI.getRelocationModel() == Reloc::PIC_ ? Mips::B 30 : Mips::J), 31 RI() {} 32 33 const MipsRegisterInfo &MipsSEInstrInfo::getRegisterInfo() const { 34 return RI; 35 } 36 37 /// isLoadFromStackSlot - If the specified machine instruction is a direct 38 /// load from a stack slot, return the virtual or physical register number of 39 /// the destination along with the FrameIndex of the loaded stack slot. If 40 /// not, return 0. This predicate must return 0 if the instruction has 41 /// any side effects other than loading from the stack slot. 42 unsigned MipsSEInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 43 int &FrameIndex) const { 44 unsigned Opc = MI->getOpcode(); 45 46 if ((Opc == Mips::LW) || (Opc == Mips::LD) || 47 (Opc == Mips::LWC1) || (Opc == Mips::LDC1) || (Opc == Mips::LDC164)) { 48 if ((MI->getOperand(1).isFI()) && // is a stack slot 49 (MI->getOperand(2).isImm()) && // the imm is zero 50 (isZeroImm(MI->getOperand(2)))) { 51 FrameIndex = MI->getOperand(1).getIndex(); 52 return MI->getOperand(0).getReg(); 53 } 54 } 55 56 return 0; 57 } 58 59 /// isStoreToStackSlot - If the specified machine instruction is a direct 60 /// store to a stack slot, return the virtual or physical register number of 61 /// the source reg along with the FrameIndex of the loaded stack slot. If 62 /// not, return 0. This predicate must return 0 if the instruction has 63 /// any side effects other than storing to the stack slot. 64 unsigned MipsSEInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 65 int &FrameIndex) const { 66 unsigned Opc = MI->getOpcode(); 67 68 if ((Opc == Mips::SW) || (Opc == Mips::SD) || 69 (Opc == Mips::SWC1) || (Opc == Mips::SDC1) || (Opc == Mips::SDC164)) { 70 if ((MI->getOperand(1).isFI()) && // is a stack slot 71 (MI->getOperand(2).isImm()) && // the imm is zero 72 (isZeroImm(MI->getOperand(2)))) { 73 FrameIndex = MI->getOperand(1).getIndex(); 74 return MI->getOperand(0).getReg(); 75 } 76 } 77 return 0; 78 } 79 80 void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 81 MachineBasicBlock::iterator I, DebugLoc DL, 82 unsigned DestReg, unsigned SrcReg, 83 bool KillSrc) const { 84 unsigned Opc = 0, ZeroReg = 0; 85 bool isMicroMips = Subtarget.inMicroMipsMode(); 86 87 if (Mips::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg. 88 if (Mips::GPR32RegClass.contains(SrcReg)) { 89 if (isMicroMips) 90 Opc = Mips::MOVE16_MM; 91 else 92 Opc = Mips::OR, ZeroReg = Mips::ZERO; 93 } else if (Mips::CCRRegClass.contains(SrcReg)) 94 Opc = Mips::CFC1; 95 else if (Mips::FGR32RegClass.contains(SrcReg)) 96 Opc = Mips::MFC1; 97 else if (Mips::HI32RegClass.contains(SrcReg)) { 98 Opc = isMicroMips ? Mips::MFHI16_MM : Mips::MFHI; 99 SrcReg = 0; 100 } else if (Mips::LO32RegClass.contains(SrcReg)) { 101 Opc = isMicroMips ? Mips::MFLO16_MM : Mips::MFLO; 102 SrcReg = 0; 103 } else if (Mips::HI32DSPRegClass.contains(SrcReg)) 104 Opc = Mips::MFHI_DSP; 105 else if (Mips::LO32DSPRegClass.contains(SrcReg)) 106 Opc = Mips::MFLO_DSP; 107 else if (Mips::DSPCCRegClass.contains(SrcReg)) { 108 BuildMI(MBB, I, DL, get(Mips::RDDSP), DestReg).addImm(1 << 4) 109 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); 110 return; 111 } 112 else if (Mips::MSACtrlRegClass.contains(SrcReg)) 113 Opc = Mips::CFCMSA; 114 } 115 else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg. 116 if (Mips::CCRRegClass.contains(DestReg)) 117 Opc = Mips::CTC1; 118 else if (Mips::FGR32RegClass.contains(DestReg)) 119 Opc = Mips::MTC1; 120 else if (Mips::HI32RegClass.contains(DestReg)) 121 Opc = Mips::MTHI, DestReg = 0; 122 else if (Mips::LO32RegClass.contains(DestReg)) 123 Opc = Mips::MTLO, DestReg = 0; 124 else if (Mips::HI32DSPRegClass.contains(DestReg)) 125 Opc = Mips::MTHI_DSP; 126 else if (Mips::LO32DSPRegClass.contains(DestReg)) 127 Opc = Mips::MTLO_DSP; 128 else if (Mips::DSPCCRegClass.contains(DestReg)) { 129 BuildMI(MBB, I, DL, get(Mips::WRDSP)) 130 .addReg(SrcReg, getKillRegState(KillSrc)).addImm(1 << 4) 131 .addReg(DestReg, RegState::ImplicitDefine); 132 return; 133 } 134 else if (Mips::MSACtrlRegClass.contains(DestReg)) 135 Opc = Mips::CTCMSA; 136 } 137 else if (Mips::FGR32RegClass.contains(DestReg, SrcReg)) 138 Opc = Mips::FMOV_S; 139 else if (Mips::AFGR64RegClass.contains(DestReg, SrcReg)) 140 Opc = Mips::FMOV_D32; 141 else if (Mips::FGR64RegClass.contains(DestReg, SrcReg)) 142 Opc = Mips::FMOV_D64; 143 else if (Mips::GPR64RegClass.contains(DestReg)) { // Copy to CPU64 Reg. 144 if (Mips::GPR64RegClass.contains(SrcReg)) 145 Opc = Mips::OR64, ZeroReg = Mips::ZERO_64; 146 else if (Mips::HI64RegClass.contains(SrcReg)) 147 Opc = Mips::MFHI64, SrcReg = 0; 148 else if (Mips::LO64RegClass.contains(SrcReg)) 149 Opc = Mips::MFLO64, SrcReg = 0; 150 else if (Mips::FGR64RegClass.contains(SrcReg)) 151 Opc = Mips::DMFC1; 152 } 153 else if (Mips::GPR64RegClass.contains(SrcReg)) { // Copy from CPU64 Reg. 154 if (Mips::HI64RegClass.contains(DestReg)) 155 Opc = Mips::MTHI64, DestReg = 0; 156 else if (Mips::LO64RegClass.contains(DestReg)) 157 Opc = Mips::MTLO64, DestReg = 0; 158 else if (Mips::FGR64RegClass.contains(DestReg)) 159 Opc = Mips::DMTC1; 160 } 161 else if (Mips::MSA128BRegClass.contains(DestReg)) { // Copy to MSA reg 162 if (Mips::MSA128BRegClass.contains(SrcReg)) 163 Opc = Mips::MOVE_V; 164 } 165 166 assert(Opc && "Cannot copy registers"); 167 168 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); 169 170 if (DestReg) 171 MIB.addReg(DestReg, RegState::Define); 172 173 if (SrcReg) 174 MIB.addReg(SrcReg, getKillRegState(KillSrc)); 175 176 if (ZeroReg) 177 MIB.addReg(ZeroReg); 178 } 179 180 void MipsSEInstrInfo:: 181 storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 182 unsigned SrcReg, bool isKill, int FI, 183 const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, 184 int64_t Offset) const { 185 DebugLoc DL; 186 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); 187 188 unsigned Opc = 0; 189 190 if (Mips::GPR32RegClass.hasSubClassEq(RC)) 191 Opc = Mips::SW; 192 else if (Mips::GPR64RegClass.hasSubClassEq(RC)) 193 Opc = Mips::SD; 194 else if (Mips::ACC64RegClass.hasSubClassEq(RC)) 195 Opc = Mips::STORE_ACC64; 196 else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC)) 197 Opc = Mips::STORE_ACC64DSP; 198 else if (Mips::ACC128RegClass.hasSubClassEq(RC)) 199 Opc = Mips::STORE_ACC128; 200 else if (Mips::DSPCCRegClass.hasSubClassEq(RC)) 201 Opc = Mips::STORE_CCOND_DSP; 202 else if (Mips::FGR32RegClass.hasSubClassEq(RC)) 203 Opc = Mips::SWC1; 204 else if (Mips::AFGR64RegClass.hasSubClassEq(RC)) 205 Opc = Mips::SDC1; 206 else if (Mips::FGR64RegClass.hasSubClassEq(RC)) 207 Opc = Mips::SDC164; 208 else if (RC->hasType(MVT::v16i8)) 209 Opc = Mips::ST_B; 210 else if (RC->hasType(MVT::v8i16) || RC->hasType(MVT::v8f16)) 211 Opc = Mips::ST_H; 212 else if (RC->hasType(MVT::v4i32) || RC->hasType(MVT::v4f32)) 213 Opc = Mips::ST_W; 214 else if (RC->hasType(MVT::v2i64) || RC->hasType(MVT::v2f64)) 215 Opc = Mips::ST_D; 216 else if (Mips::LO32RegClass.hasSubClassEq(RC)) 217 Opc = Mips::SW; 218 else if (Mips::LO64RegClass.hasSubClassEq(RC)) 219 Opc = Mips::SD; 220 else if (Mips::HI32RegClass.hasSubClassEq(RC)) 221 Opc = Mips::SW; 222 else if (Mips::HI64RegClass.hasSubClassEq(RC)) 223 Opc = Mips::SD; 224 225 // Hi, Lo are normally caller save but they are callee save 226 // for interrupt handling. 227 const Function *Func = MBB.getParent()->getFunction(); 228 if (Func->hasFnAttribute("interrupt")) { 229 if (Mips::HI32RegClass.hasSubClassEq(RC)) { 230 BuildMI(MBB, I, DL, get(Mips::MFHI), Mips::K0); 231 SrcReg = Mips::K0; 232 } else if (Mips::HI64RegClass.hasSubClassEq(RC)) { 233 BuildMI(MBB, I, DL, get(Mips::MFHI64), Mips::K0_64); 234 SrcReg = Mips::K0_64; 235 } else if (Mips::LO32RegClass.hasSubClassEq(RC)) { 236 BuildMI(MBB, I, DL, get(Mips::MFLO), Mips::K0); 237 SrcReg = Mips::K0; 238 } else if (Mips::LO64RegClass.hasSubClassEq(RC)) { 239 BuildMI(MBB, I, DL, get(Mips::MFLO64), Mips::K0_64); 240 SrcReg = Mips::K0_64; 241 } 242 } 243 244 assert(Opc && "Register class not handled!"); 245 BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)) 246 .addFrameIndex(FI).addImm(Offset).addMemOperand(MMO); 247 } 248 249 void MipsSEInstrInfo:: 250 loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 251 unsigned DestReg, int FI, const TargetRegisterClass *RC, 252 const TargetRegisterInfo *TRI, int64_t Offset) const { 253 DebugLoc DL; 254 if (I != MBB.end()) DL = I->getDebugLoc(); 255 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); 256 unsigned Opc = 0; 257 258 const Function *Func = MBB.getParent()->getFunction(); 259 bool ReqIndirectLoad = Func->hasFnAttribute("interrupt") && 260 (DestReg == Mips::LO0 || DestReg == Mips::LO0_64 || 261 DestReg == Mips::HI0 || DestReg == Mips::HI0_64); 262 263 if (Mips::GPR32RegClass.hasSubClassEq(RC)) 264 Opc = Mips::LW; 265 else if (Mips::GPR64RegClass.hasSubClassEq(RC)) 266 Opc = Mips::LD; 267 else if (Mips::ACC64RegClass.hasSubClassEq(RC)) 268 Opc = Mips::LOAD_ACC64; 269 else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC)) 270 Opc = Mips::LOAD_ACC64DSP; 271 else if (Mips::ACC128RegClass.hasSubClassEq(RC)) 272 Opc = Mips::LOAD_ACC128; 273 else if (Mips::DSPCCRegClass.hasSubClassEq(RC)) 274 Opc = Mips::LOAD_CCOND_DSP; 275 else if (Mips::FGR32RegClass.hasSubClassEq(RC)) 276 Opc = Mips::LWC1; 277 else if (Mips::AFGR64RegClass.hasSubClassEq(RC)) 278 Opc = Mips::LDC1; 279 else if (Mips::FGR64RegClass.hasSubClassEq(RC)) 280 Opc = Mips::LDC164; 281 else if (RC->hasType(MVT::v16i8)) 282 Opc = Mips::LD_B; 283 else if (RC->hasType(MVT::v8i16) || RC->hasType(MVT::v8f16)) 284 Opc = Mips::LD_H; 285 else if (RC->hasType(MVT::v4i32) || RC->hasType(MVT::v4f32)) 286 Opc = Mips::LD_W; 287 else if (RC->hasType(MVT::v2i64) || RC->hasType(MVT::v2f64)) 288 Opc = Mips::LD_D; 289 else if (Mips::HI32RegClass.hasSubClassEq(RC)) 290 Opc = Mips::LW; 291 else if (Mips::HI64RegClass.hasSubClassEq(RC)) 292 Opc = Mips::LD; 293 else if (Mips::LO32RegClass.hasSubClassEq(RC)) 294 Opc = Mips::LW; 295 else if (Mips::LO64RegClass.hasSubClassEq(RC)) 296 Opc = Mips::LD; 297 298 assert(Opc && "Register class not handled!"); 299 300 if (!ReqIndirectLoad) 301 BuildMI(MBB, I, DL, get(Opc), DestReg) 302 .addFrameIndex(FI) 303 .addImm(Offset) 304 .addMemOperand(MMO); 305 else { 306 // Load HI/LO through K0. Notably the DestReg is encoded into the 307 // instruction itself. 308 unsigned Reg = Mips::K0; 309 unsigned LdOp = Mips::MTLO; 310 if (DestReg == Mips::HI0) 311 LdOp = Mips::MTHI; 312 313 if (Subtarget.getABI().ArePtrs64bit()) { 314 Reg = Mips::K0_64; 315 if (DestReg == Mips::HI0_64) 316 LdOp = Mips::MTHI64; 317 else 318 LdOp = Mips::MTLO64; 319 } 320 321 BuildMI(MBB, I, DL, get(Opc), Reg) 322 .addFrameIndex(FI) 323 .addImm(Offset) 324 .addMemOperand(MMO); 325 BuildMI(MBB, I, DL, get(LdOp)).addReg(Reg); 326 } 327 } 328 329 bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 330 MachineBasicBlock &MBB = *MI->getParent(); 331 bool isMicroMips = Subtarget.inMicroMipsMode(); 332 unsigned Opc; 333 334 switch(MI->getDesc().getOpcode()) { 335 default: 336 return false; 337 case Mips::RetRA: 338 expandRetRA(MBB, MI); 339 break; 340 case Mips::ERet: 341 expandERet(MBB, MI); 342 break; 343 case Mips::PseudoMFHI: 344 Opc = isMicroMips ? Mips::MFHI16_MM : Mips::MFHI; 345 expandPseudoMFHiLo(MBB, MI, Opc); 346 break; 347 case Mips::PseudoMFLO: 348 Opc = isMicroMips ? Mips::MFLO16_MM : Mips::MFLO; 349 expandPseudoMFHiLo(MBB, MI, Opc); 350 break; 351 case Mips::PseudoMFHI64: 352 expandPseudoMFHiLo(MBB, MI, Mips::MFHI64); 353 break; 354 case Mips::PseudoMFLO64: 355 expandPseudoMFHiLo(MBB, MI, Mips::MFLO64); 356 break; 357 case Mips::PseudoMTLOHI: 358 expandPseudoMTLoHi(MBB, MI, Mips::MTLO, Mips::MTHI, false); 359 break; 360 case Mips::PseudoMTLOHI64: 361 expandPseudoMTLoHi(MBB, MI, Mips::MTLO64, Mips::MTHI64, false); 362 break; 363 case Mips::PseudoMTLOHI_DSP: 364 expandPseudoMTLoHi(MBB, MI, Mips::MTLO_DSP, Mips::MTHI_DSP, true); 365 break; 366 case Mips::PseudoCVT_S_W: 367 expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false); 368 break; 369 case Mips::PseudoCVT_D32_W: 370 expandCvtFPInt(MBB, MI, Mips::CVT_D32_W, Mips::MTC1, false); 371 break; 372 case Mips::PseudoCVT_S_L: 373 expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, true); 374 break; 375 case Mips::PseudoCVT_D64_W: 376 expandCvtFPInt(MBB, MI, Mips::CVT_D64_W, Mips::MTC1, true); 377 break; 378 case Mips::PseudoCVT_D64_L: 379 expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true); 380 break; 381 case Mips::BuildPairF64: 382 expandBuildPairF64(MBB, MI, false); 383 break; 384 case Mips::BuildPairF64_64: 385 expandBuildPairF64(MBB, MI, true); 386 break; 387 case Mips::ExtractElementF64: 388 expandExtractElementF64(MBB, MI, false); 389 break; 390 case Mips::ExtractElementF64_64: 391 expandExtractElementF64(MBB, MI, true); 392 break; 393 case Mips::MIPSeh_return32: 394 case Mips::MIPSeh_return64: 395 expandEhReturn(MBB, MI); 396 break; 397 } 398 399 MBB.erase(MI); 400 return true; 401 } 402 403 /// getOppositeBranchOpc - Return the inverse of the specified 404 /// opcode, e.g. turning BEQ to BNE. 405 unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const { 406 switch (Opc) { 407 default: llvm_unreachable("Illegal opcode!"); 408 case Mips::BEQ: return Mips::BNE; 409 case Mips::BNE: return Mips::BEQ; 410 case Mips::BGTZ: return Mips::BLEZ; 411 case Mips::BGEZ: return Mips::BLTZ; 412 case Mips::BLTZ: return Mips::BGEZ; 413 case Mips::BLEZ: return Mips::BGTZ; 414 case Mips::BEQ64: return Mips::BNE64; 415 case Mips::BNE64: return Mips::BEQ64; 416 case Mips::BGTZ64: return Mips::BLEZ64; 417 case Mips::BGEZ64: return Mips::BLTZ64; 418 case Mips::BLTZ64: return Mips::BGEZ64; 419 case Mips::BLEZ64: return Mips::BGTZ64; 420 case Mips::BC1T: return Mips::BC1F; 421 case Mips::BC1F: return Mips::BC1T; 422 case Mips::BEQZC_MM: return Mips::BNEZC_MM; 423 case Mips::BNEZC_MM: return Mips::BEQZC_MM; 424 } 425 } 426 427 /// Adjust SP by Amount bytes. 428 void MipsSEInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, 429 MachineBasicBlock &MBB, 430 MachineBasicBlock::iterator I) const { 431 MipsABIInfo ABI = Subtarget.getABI(); 432 DebugLoc DL; 433 unsigned ADDu = ABI.GetPtrAdduOp(); 434 unsigned ADDiu = ABI.GetPtrAddiuOp(); 435 436 if (Amount == 0) 437 return; 438 439 if (isInt<16>(Amount))// addi sp, sp, amount 440 BuildMI(MBB, I, DL, get(ADDiu), SP).addReg(SP).addImm(Amount); 441 else { // Expand immediate that doesn't fit in 16-bit. 442 unsigned Reg = loadImmediate(Amount, MBB, I, DL, nullptr); 443 BuildMI(MBB, I, DL, get(ADDu), SP).addReg(SP).addReg(Reg, RegState::Kill); 444 } 445 } 446 447 /// This function generates the sequence of instructions needed to get the 448 /// result of adding register REG and immediate IMM. 449 unsigned 450 MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB, 451 MachineBasicBlock::iterator II, DebugLoc DL, 452 unsigned *NewImm) const { 453 MipsAnalyzeImmediate AnalyzeImm; 454 const MipsSubtarget &STI = Subtarget; 455 MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); 456 unsigned Size = STI.isABI_N64() ? 64 : 32; 457 unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi; 458 unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; 459 const TargetRegisterClass *RC = STI.isABI_N64() ? 460 &Mips::GPR64RegClass : &Mips::GPR32RegClass; 461 bool LastInstrIsADDiu = NewImm; 462 463 const MipsAnalyzeImmediate::InstSeq &Seq = 464 AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu); 465 MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); 466 467 assert(Seq.size() && (!LastInstrIsADDiu || (Seq.size() > 1))); 468 469 // The first instruction can be a LUi, which is different from other 470 // instructions (ADDiu, ORI and SLL) in that it does not have a register 471 // operand. 472 unsigned Reg = RegInfo.createVirtualRegister(RC); 473 474 if (Inst->Opc == LUi) 475 BuildMI(MBB, II, DL, get(LUi), Reg).addImm(SignExtend64<16>(Inst->ImmOpnd)); 476 else 477 BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(ZEROReg) 478 .addImm(SignExtend64<16>(Inst->ImmOpnd)); 479 480 // Build the remaining instructions in Seq. 481 for (++Inst; Inst != Seq.end() - LastInstrIsADDiu; ++Inst) 482 BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(Reg, RegState::Kill) 483 .addImm(SignExtend64<16>(Inst->ImmOpnd)); 484 485 if (LastInstrIsADDiu) 486 *NewImm = Inst->ImmOpnd; 487 488 return Reg; 489 } 490 491 unsigned MipsSEInstrInfo::getAnalyzableBrOpc(unsigned Opc) const { 492 return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ || 493 Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ || 494 Opc == Mips::BEQ64 || Opc == Mips::BNE64 || Opc == Mips::BGTZ64 || 495 Opc == Mips::BGEZ64 || Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 || 496 Opc == Mips::BC1T || Opc == Mips::BC1F || Opc == Mips::B || 497 Opc == Mips::J || Opc == Mips::BEQZC_MM || Opc == Mips::BNEZC_MM) ? 498 Opc : 0; 499 } 500 501 void MipsSEInstrInfo::expandRetRA(MachineBasicBlock &MBB, 502 MachineBasicBlock::iterator I) const { 503 if (Subtarget.isGP64bit()) 504 BuildMI(MBB, I, I->getDebugLoc(), get(Mips::PseudoReturn64)) 505 .addReg(Mips::RA_64); 506 else 507 BuildMI(MBB, I, I->getDebugLoc(), get(Mips::PseudoReturn)).addReg(Mips::RA); 508 } 509 510 void MipsSEInstrInfo::expandERet(MachineBasicBlock &MBB, 511 MachineBasicBlock::iterator I) const { 512 BuildMI(MBB, I, I->getDebugLoc(), get(Mips::ERET)); 513 } 514 515 std::pair<bool, bool> 516 MipsSEInstrInfo::compareOpndSize(unsigned Opc, 517 const MachineFunction &MF) const { 518 const MCInstrDesc &Desc = get(Opc); 519 assert(Desc.NumOperands == 2 && "Unary instruction expected."); 520 const MipsRegisterInfo *RI = &getRegisterInfo(); 521 unsigned DstRegSize = getRegClass(Desc, 0, RI, MF)->getSize(); 522 unsigned SrcRegSize = getRegClass(Desc, 1, RI, MF)->getSize(); 523 524 return std::make_pair(DstRegSize > SrcRegSize, DstRegSize < SrcRegSize); 525 } 526 527 void MipsSEInstrInfo::expandPseudoMFHiLo(MachineBasicBlock &MBB, 528 MachineBasicBlock::iterator I, 529 unsigned NewOpc) const { 530 BuildMI(MBB, I, I->getDebugLoc(), get(NewOpc), I->getOperand(0).getReg()); 531 } 532 533 void MipsSEInstrInfo::expandPseudoMTLoHi(MachineBasicBlock &MBB, 534 MachineBasicBlock::iterator I, 535 unsigned LoOpc, 536 unsigned HiOpc, 537 bool HasExplicitDef) const { 538 // Expand 539 // lo_hi pseudomtlohi $gpr0, $gpr1 540 // to these two instructions: 541 // mtlo $gpr0 542 // mthi $gpr1 543 544 DebugLoc DL = I->getDebugLoc(); 545 const MachineOperand &SrcLo = I->getOperand(1), &SrcHi = I->getOperand(2); 546 MachineInstrBuilder LoInst = BuildMI(MBB, I, DL, get(LoOpc)); 547 MachineInstrBuilder HiInst = BuildMI(MBB, I, DL, get(HiOpc)); 548 549 // Add lo/hi registers if the mtlo/hi instructions created have explicit 550 // def registers. 551 if (HasExplicitDef) { 552 unsigned DstReg = I->getOperand(0).getReg(); 553 unsigned DstLo = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo); 554 unsigned DstHi = getRegisterInfo().getSubReg(DstReg, Mips::sub_hi); 555 LoInst.addReg(DstLo, RegState::Define); 556 HiInst.addReg(DstHi, RegState::Define); 557 } 558 559 LoInst.addReg(SrcLo.getReg(), getKillRegState(SrcLo.isKill())); 560 HiInst.addReg(SrcHi.getReg(), getKillRegState(SrcHi.isKill())); 561 } 562 563 void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB, 564 MachineBasicBlock::iterator I, 565 unsigned CvtOpc, unsigned MovOpc, 566 bool IsI64) const { 567 const MCInstrDesc &CvtDesc = get(CvtOpc), &MovDesc = get(MovOpc); 568 const MachineOperand &Dst = I->getOperand(0), &Src = I->getOperand(1); 569 unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg; 570 unsigned KillSrc = getKillRegState(Src.isKill()); 571 DebugLoc DL = I->getDebugLoc(); 572 bool DstIsLarger, SrcIsLarger; 573 574 std::tie(DstIsLarger, SrcIsLarger) = 575 compareOpndSize(CvtOpc, *MBB.getParent()); 576 577 if (DstIsLarger) 578 TmpReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo); 579 580 if (SrcIsLarger) 581 DstReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo); 582 583 BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc); 584 BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill); 585 } 586 587 void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB, 588 MachineBasicBlock::iterator I, 589 bool FP64) const { 590 unsigned DstReg = I->getOperand(0).getReg(); 591 unsigned SrcReg = I->getOperand(1).getReg(); 592 unsigned N = I->getOperand(2).getImm(); 593 DebugLoc dl = I->getDebugLoc(); 594 595 assert(N < 2 && "Invalid immediate"); 596 unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo; 597 unsigned SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx); 598 599 // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload 600 // in MipsSEFrameLowering.cpp. 601 assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2())); 602 603 // FP64A (FP64 with nooddspreg) should have been handled with a spill/reload 604 // in MipsSEFrameLowering.cpp. 605 assert(!(Subtarget.isFP64bit() && !Subtarget.useOddSPReg())); 606 607 if (SubIdx == Mips::sub_hi && Subtarget.hasMTHC1()) { 608 // FIXME: Strictly speaking MFHC1 only reads the top 32-bits however, we 609 // claim to read the whole 64-bits as part of a white lie used to 610 // temporarily work around a widespread bug in the -mfp64 support. 611 // The problem is that none of the 32-bit fpu ops mention the fact 612 // that they clobber the upper 32-bits of the 64-bit FPR. Fixing that 613 // requires a major overhaul of the FPU implementation which can't 614 // be done right now due to time constraints. 615 // MFHC1 is one of two instructions that are affected since they are 616 // the only instructions that don't read the lower 32-bits. 617 // We therefore pretend that it reads the bottom 32-bits to 618 // artificially create a dependency and prevent the scheduler 619 // changing the behaviour of the code. 620 BuildMI(MBB, I, dl, get(FP64 ? Mips::MFHC1_D64 : Mips::MFHC1_D32), DstReg) 621 .addReg(SrcReg); 622 } else 623 BuildMI(MBB, I, dl, get(Mips::MFC1), DstReg).addReg(SubReg); 624 } 625 626 void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB, 627 MachineBasicBlock::iterator I, 628 bool FP64) const { 629 unsigned DstReg = I->getOperand(0).getReg(); 630 unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg(); 631 const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1); 632 DebugLoc dl = I->getDebugLoc(); 633 const TargetRegisterInfo &TRI = getRegisterInfo(); 634 635 // When mthc1 is available, use: 636 // mtc1 Lo, $fp 637 // mthc1 Hi, $fp 638 // 639 // Otherwise, for O32 FPXX ABI: 640 // spill + reload via ldc1 641 // This case is handled by the frame lowering code. 642 // 643 // Otherwise, for FP32: 644 // mtc1 Lo, $fp 645 // mtc1 Hi, $fp + 1 646 // 647 // The case where dmtc1 is available doesn't need to be handled here 648 // because it never creates a BuildPairF64 node. 649 650 // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload 651 // in MipsSEFrameLowering.cpp. 652 assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2())); 653 654 // FP64A (FP64 with nooddspreg) should have been handled with a spill/reload 655 // in MipsSEFrameLowering.cpp. 656 assert(!(Subtarget.isFP64bit() && !Subtarget.useOddSPReg())); 657 658 BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo)) 659 .addReg(LoReg); 660 661 if (Subtarget.hasMTHC1()) { 662 // FIXME: The .addReg(DstReg) is a white lie used to temporarily work 663 // around a widespread bug in the -mfp64 support. 664 // The problem is that none of the 32-bit fpu ops mention the fact 665 // that they clobber the upper 32-bits of the 64-bit FPR. Fixing that 666 // requires a major overhaul of the FPU implementation which can't 667 // be done right now due to time constraints. 668 // MTHC1 is one of two instructions that are affected since they are 669 // the only instructions that don't read the lower 32-bits. 670 // We therefore pretend that it reads the bottom 32-bits to 671 // artificially create a dependency and prevent the scheduler 672 // changing the behaviour of the code. 673 BuildMI(MBB, I, dl, get(FP64 ? Mips::MTHC1_D64 : Mips::MTHC1_D32), DstReg) 674 .addReg(DstReg) 675 .addReg(HiReg); 676 } else if (Subtarget.isABI_FPXX()) 677 llvm_unreachable("BuildPairF64 not expanded in frame lowering code!"); 678 else 679 BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi)) 680 .addReg(HiReg); 681 } 682 683 void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB, 684 MachineBasicBlock::iterator I) const { 685 // This pseudo instruction is generated as part of the lowering of 686 // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and 687 // indirect jump to TargetReg 688 MipsABIInfo ABI = Subtarget.getABI(); 689 unsigned ADDU = ABI.GetPtrAdduOp(); 690 unsigned SP = Subtarget.isGP64bit() ? Mips::SP_64 : Mips::SP; 691 unsigned RA = Subtarget.isGP64bit() ? Mips::RA_64 : Mips::RA; 692 unsigned T9 = Subtarget.isGP64bit() ? Mips::T9_64 : Mips::T9; 693 unsigned ZERO = Subtarget.isGP64bit() ? Mips::ZERO_64 : Mips::ZERO; 694 unsigned OffsetReg = I->getOperand(0).getReg(); 695 unsigned TargetReg = I->getOperand(1).getReg(); 696 697 // addu $ra, $v0, $zero 698 // addu $sp, $sp, $v1 699 // jr $ra (via RetRA) 700 const TargetMachine &TM = MBB.getParent()->getTarget(); 701 if (TM.getRelocationModel() == Reloc::PIC_) 702 BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), T9) 703 .addReg(TargetReg) 704 .addReg(ZERO); 705 BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), RA) 706 .addReg(TargetReg) 707 .addReg(ZERO); 708 BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), SP).addReg(SP).addReg(OffsetReg); 709 expandRetRA(MBB, I); 710 } 711 712 const MipsInstrInfo *llvm::createMipsSEInstrInfo(const MipsSubtarget &STI) { 713 return new MipsSEInstrInfo(STI); 714 } 715