1 //===- MipsInstructionSelector.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 InstructionSelector class for 10 /// Mips. 11 /// \todo This should be generated by TableGen. 12 //===----------------------------------------------------------------------===// 13 14 #include "MCTargetDesc/MipsInstPrinter.h" 15 #include "MipsMachineFunction.h" 16 #include "MipsRegisterBankInfo.h" 17 #include "MipsTargetMachine.h" 18 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" 19 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 20 #include "llvm/CodeGen/MachineJumpTableInfo.h" 21 22 #define DEBUG_TYPE "mips-isel" 23 24 using namespace llvm; 25 26 namespace { 27 28 #define GET_GLOBALISEL_PREDICATE_BITSET 29 #include "MipsGenGlobalISel.inc" 30 #undef GET_GLOBALISEL_PREDICATE_BITSET 31 32 class MipsInstructionSelector : public InstructionSelector { 33 public: 34 MipsInstructionSelector(const MipsTargetMachine &TM, const MipsSubtarget &STI, 35 const MipsRegisterBankInfo &RBI); 36 37 bool select(MachineInstr &I) override; 38 static const char *getName() { return DEBUG_TYPE; } 39 40 private: 41 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; 42 bool materialize32BitImm(Register DestReg, APInt Imm, 43 MachineIRBuilder &B) const; 44 bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const; 45 const TargetRegisterClass * 46 getRegClassForTypeOnBank(unsigned OpSize, const RegisterBank &RB, 47 const RegisterBankInfo &RBI) const; 48 49 const MipsTargetMachine &TM; 50 const MipsSubtarget &STI; 51 const MipsInstrInfo &TII; 52 const MipsRegisterInfo &TRI; 53 const MipsRegisterBankInfo &RBI; 54 55 #define GET_GLOBALISEL_PREDICATES_DECL 56 #include "MipsGenGlobalISel.inc" 57 #undef GET_GLOBALISEL_PREDICATES_DECL 58 59 #define GET_GLOBALISEL_TEMPORARIES_DECL 60 #include "MipsGenGlobalISel.inc" 61 #undef GET_GLOBALISEL_TEMPORARIES_DECL 62 }; 63 64 } // end anonymous namespace 65 66 #define GET_GLOBALISEL_IMPL 67 #include "MipsGenGlobalISel.inc" 68 #undef GET_GLOBALISEL_IMPL 69 70 MipsInstructionSelector::MipsInstructionSelector( 71 const MipsTargetMachine &TM, const MipsSubtarget &STI, 72 const MipsRegisterBankInfo &RBI) 73 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), 74 TRI(*STI.getRegisterInfo()), RBI(RBI), 75 76 #define GET_GLOBALISEL_PREDICATES_INIT 77 #include "MipsGenGlobalISel.inc" 78 #undef GET_GLOBALISEL_PREDICATES_INIT 79 #define GET_GLOBALISEL_TEMPORARIES_INIT 80 #include "MipsGenGlobalISel.inc" 81 #undef GET_GLOBALISEL_TEMPORARIES_INIT 82 { 83 } 84 85 bool MipsInstructionSelector::selectCopy(MachineInstr &I, 86 MachineRegisterInfo &MRI) const { 87 Register DstReg = I.getOperand(0).getReg(); 88 if (Register::isPhysicalRegister(DstReg)) 89 return true; 90 91 const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI); 92 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); 93 94 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 95 if (RegBank->getID() == Mips::FPRBRegBankID) { 96 if (DstSize == 32) 97 RC = &Mips::FGR32RegClass; 98 else if (DstSize == 64) 99 RC = STI.isFP64bit() ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass; 100 else 101 llvm_unreachable("Unsupported destination size"); 102 } 103 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { 104 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 105 << " operand\n"); 106 return false; 107 } 108 return true; 109 } 110 111 const TargetRegisterClass *MipsInstructionSelector::getRegClassForTypeOnBank( 112 unsigned OpSize, const RegisterBank &RB, 113 const RegisterBankInfo &RBI) const { 114 if (RB.getID() == Mips::GPRBRegBankID) 115 return &Mips::GPR32RegClass; 116 117 if (RB.getID() == Mips::FPRBRegBankID) 118 return OpSize == 32 119 ? &Mips::FGR32RegClass 120 : STI.hasMips32r6() || STI.isFP64bit() ? &Mips::FGR64RegClass 121 : &Mips::AFGR64RegClass; 122 123 llvm_unreachable("getRegClassForTypeOnBank can't find register class."); 124 return nullptr; 125 } 126 127 bool MipsInstructionSelector::materialize32BitImm(Register DestReg, APInt Imm, 128 MachineIRBuilder &B) const { 129 assert(Imm.getBitWidth() == 32 && "Unsupported immediate size."); 130 // Ori zero extends immediate. Used for values with zeros in high 16 bits. 131 if (Imm.getHiBits(16).isNullValue()) { 132 MachineInstr *Inst = B.buildInstr(Mips::ORi, {DestReg}, {Register(Mips::ZERO)}) 133 .addImm(Imm.getLoBits(16).getLimitedValue()); 134 return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI); 135 } 136 // Lui places immediate in high 16 bits and sets low 16 bits to zero. 137 if (Imm.getLoBits(16).isNullValue()) { 138 MachineInstr *Inst = B.buildInstr(Mips::LUi, {DestReg}, {}) 139 .addImm(Imm.getHiBits(16).getLimitedValue()); 140 return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI); 141 } 142 // ADDiu sign extends immediate. Used for values with 1s in high 17 bits. 143 if (Imm.isSignedIntN(16)) { 144 MachineInstr *Inst = B.buildInstr(Mips::ADDiu, {DestReg}, {Register(Mips::ZERO)}) 145 .addImm(Imm.getLoBits(16).getLimitedValue()); 146 return constrainSelectedInstRegOperands(*Inst, TII, TRI, RBI); 147 } 148 // Values that cannot be materialized with single immediate instruction. 149 Register LUiReg = B.getMRI()->createVirtualRegister(&Mips::GPR32RegClass); 150 MachineInstr *LUi = B.buildInstr(Mips::LUi, {LUiReg}, {}) 151 .addImm(Imm.getHiBits(16).getLimitedValue()); 152 MachineInstr *ORi = B.buildInstr(Mips::ORi, {DestReg}, {LUiReg}) 153 .addImm(Imm.getLoBits(16).getLimitedValue()); 154 if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI)) 155 return false; 156 if (!constrainSelectedInstRegOperands(*ORi, TII, TRI, RBI)) 157 return false; 158 return true; 159 } 160 161 /// Returning Opc indicates that we failed to select MIPS instruction opcode. 162 static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned MemSizeInBytes, 163 unsigned RegBank, bool isFP64) { 164 bool isStore = Opc == TargetOpcode::G_STORE; 165 if (RegBank == Mips::GPRBRegBankID) { 166 if (isStore) 167 switch (MemSizeInBytes) { 168 case 4: 169 return Mips::SW; 170 case 2: 171 return Mips::SH; 172 case 1: 173 return Mips::SB; 174 default: 175 return Opc; 176 } 177 else 178 // Unspecified extending load is selected into zeroExtending load. 179 switch (MemSizeInBytes) { 180 case 4: 181 return Mips::LW; 182 case 2: 183 return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LH : Mips::LHu; 184 case 1: 185 return Opc == TargetOpcode::G_SEXTLOAD ? Mips::LB : Mips::LBu; 186 default: 187 return Opc; 188 } 189 } 190 191 if (RegBank == Mips::FPRBRegBankID) { 192 switch (MemSizeInBytes) { 193 case 4: 194 return isStore ? Mips::SWC1 : Mips::LWC1; 195 case 8: 196 if (isFP64) 197 return isStore ? Mips::SDC164 : Mips::LDC164; 198 else 199 return isStore ? Mips::SDC1 : Mips::LDC1; 200 default: 201 return Opc; 202 } 203 } 204 return Opc; 205 } 206 207 bool MipsInstructionSelector::select(MachineInstr &I) { 208 209 MachineBasicBlock &MBB = *I.getParent(); 210 MachineFunction &MF = *MBB.getParent(); 211 MachineRegisterInfo &MRI = MF.getRegInfo(); 212 213 if (!isPreISelGenericOpcode(I.getOpcode())) { 214 if (I.isCopy()) 215 return selectCopy(I, MRI); 216 217 return true; 218 } 219 220 if (I.getOpcode() == Mips::G_MUL) { 221 MachineInstr *Mul = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MUL)) 222 .add(I.getOperand(0)) 223 .add(I.getOperand(1)) 224 .add(I.getOperand(2)); 225 if (!constrainSelectedInstRegOperands(*Mul, TII, TRI, RBI)) 226 return false; 227 Mul->getOperand(3).setIsDead(true); 228 Mul->getOperand(4).setIsDead(true); 229 230 I.eraseFromParent(); 231 return true; 232 } 233 234 if (selectImpl(I, *CoverageInfo)) 235 return true; 236 237 MachineInstr *MI = nullptr; 238 using namespace TargetOpcode; 239 240 switch (I.getOpcode()) { 241 case G_UMULH: { 242 Register PseudoMULTuReg = MRI.createVirtualRegister(&Mips::ACC64RegClass); 243 MachineInstr *PseudoMULTu, *PseudoMove; 244 245 PseudoMULTu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMULTu)) 246 .addDef(PseudoMULTuReg) 247 .add(I.getOperand(1)) 248 .add(I.getOperand(2)); 249 if (!constrainSelectedInstRegOperands(*PseudoMULTu, TII, TRI, RBI)) 250 return false; 251 252 PseudoMove = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMFHI)) 253 .addDef(I.getOperand(0).getReg()) 254 .addUse(PseudoMULTuReg); 255 if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI)) 256 return false; 257 258 I.eraseFromParent(); 259 return true; 260 } 261 case G_GEP: { 262 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu)) 263 .add(I.getOperand(0)) 264 .add(I.getOperand(1)) 265 .add(I.getOperand(2)); 266 break; 267 } 268 case G_INTTOPTR: 269 case G_PTRTOINT: { 270 I.setDesc(TII.get(COPY)); 271 return selectCopy(I, MRI); 272 } 273 case G_FRAME_INDEX: { 274 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) 275 .add(I.getOperand(0)) 276 .add(I.getOperand(1)) 277 .addImm(0); 278 break; 279 } 280 case G_BRCOND: { 281 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::BNE)) 282 .add(I.getOperand(0)) 283 .addUse(Mips::ZERO) 284 .add(I.getOperand(1)); 285 break; 286 } 287 case G_BRJT: { 288 unsigned EntrySize = 289 MF.getJumpTableInfo()->getEntrySize(MF.getDataLayout()); 290 assert(isPowerOf2_32(EntrySize) && 291 "Non-power-of-two jump-table entry size not supported."); 292 293 Register JTIndex = MRI.createVirtualRegister(&Mips::GPR32RegClass); 294 MachineInstr *SLL = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::SLL)) 295 .addDef(JTIndex) 296 .addUse(I.getOperand(2).getReg()) 297 .addImm(Log2_32(EntrySize)); 298 if (!constrainSelectedInstRegOperands(*SLL, TII, TRI, RBI)) 299 return false; 300 301 Register DestAddress = MRI.createVirtualRegister(&Mips::GPR32RegClass); 302 MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu)) 303 .addDef(DestAddress) 304 .addUse(I.getOperand(0).getReg()) 305 .addUse(JTIndex); 306 if (!constrainSelectedInstRegOperands(*ADDu, TII, TRI, RBI)) 307 return false; 308 309 Register Dest = MRI.createVirtualRegister(&Mips::GPR32RegClass); 310 MachineInstr *LW = 311 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW)) 312 .addDef(Dest) 313 .addUse(DestAddress) 314 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_LO) 315 .addMemOperand(MF.getMachineMemOperand( 316 MachinePointerInfo(), MachineMemOperand::MOLoad, 4, 4)); 317 if (!constrainSelectedInstRegOperands(*LW, TII, TRI, RBI)) 318 return false; 319 320 if (MF.getTarget().isPositionIndependent()) { 321 Register DestTmp = MRI.createVirtualRegister(&Mips::GPR32RegClass); 322 LW->getOperand(0).setReg(DestTmp); 323 MachineInstr *ADDu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDu)) 324 .addDef(Dest) 325 .addUse(DestTmp) 326 .addUse(MF.getInfo<MipsFunctionInfo>() 327 ->getGlobalBaseRegForGlobalISel()); 328 if (!constrainSelectedInstRegOperands(*ADDu, TII, TRI, RBI)) 329 return false; 330 } 331 332 MachineInstr *Branch = 333 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoIndirectBranch)) 334 .addUse(Dest); 335 if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI)) 336 return false; 337 338 I.eraseFromParent(); 339 return true; 340 } 341 case G_PHI: { 342 const Register DestReg = I.getOperand(0).getReg(); 343 const unsigned OpSize = MRI.getType(DestReg).getSizeInBits(); 344 345 const TargetRegisterClass *DefRC = nullptr; 346 if (Register::isPhysicalRegister(DestReg)) 347 DefRC = TRI.getRegClass(DestReg); 348 else 349 DefRC = getRegClassForTypeOnBank(OpSize, 350 *RBI.getRegBank(DestReg, MRI, TRI), RBI); 351 352 I.setDesc(TII.get(TargetOpcode::PHI)); 353 return RBI.constrainGenericRegister(DestReg, *DefRC, MRI); 354 } 355 case G_STORE: 356 case G_LOAD: 357 case G_ZEXTLOAD: 358 case G_SEXTLOAD: { 359 const Register DestReg = I.getOperand(0).getReg(); 360 const unsigned DestRegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID(); 361 const unsigned OpSize = MRI.getType(DestReg).getSizeInBits(); 362 const unsigned OpMemSizeInBytes = (*I.memoperands_begin())->getSize(); 363 364 if (DestRegBank == Mips::GPRBRegBankID && OpSize != 32) 365 return false; 366 367 if (DestRegBank == Mips::FPRBRegBankID && OpSize != 32 && OpSize != 64) 368 return false; 369 370 const unsigned NewOpc = selectLoadStoreOpCode( 371 I.getOpcode(), OpMemSizeInBytes, DestRegBank, STI.isFP64bit()); 372 if (NewOpc == I.getOpcode()) 373 return false; 374 375 MachineOperand BaseAddr = I.getOperand(1); 376 int64_t SignedOffset = 0; 377 // Try to fold load/store + G_GEP + G_CONSTANT 378 // %SignedOffset:(s32) = G_CONSTANT i32 16_bit_signed_immediate 379 // %Addr:(p0) = G_GEP %BaseAddr, %SignedOffset 380 // %LoadResult/%StoreSrc = load/store %Addr(p0) 381 // into: 382 // %LoadResult/%StoreSrc = NewOpc %BaseAddr(p0), 16_bit_signed_immediate 383 384 MachineInstr *Addr = MRI.getVRegDef(I.getOperand(1).getReg()); 385 if (Addr->getOpcode() == G_GEP) { 386 MachineInstr *Offset = MRI.getVRegDef(Addr->getOperand(2).getReg()); 387 if (Offset->getOpcode() == G_CONSTANT) { 388 APInt OffsetValue = Offset->getOperand(1).getCImm()->getValue(); 389 if (OffsetValue.isSignedIntN(16)) { 390 BaseAddr = Addr->getOperand(1); 391 SignedOffset = OffsetValue.getSExtValue(); 392 } 393 } 394 } 395 396 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc)) 397 .add(I.getOperand(0)) 398 .add(BaseAddr) 399 .addImm(SignedOffset) 400 .addMemOperand(*I.memoperands_begin()); 401 break; 402 } 403 case G_UDIV: 404 case G_UREM: 405 case G_SDIV: 406 case G_SREM: { 407 Register HILOReg = MRI.createVirtualRegister(&Mips::ACC64RegClass); 408 bool IsSigned = I.getOpcode() == G_SREM || I.getOpcode() == G_SDIV; 409 bool IsDiv = I.getOpcode() == G_UDIV || I.getOpcode() == G_SDIV; 410 411 MachineInstr *PseudoDIV, *PseudoMove; 412 PseudoDIV = BuildMI(MBB, I, I.getDebugLoc(), 413 TII.get(IsSigned ? Mips::PseudoSDIV : Mips::PseudoUDIV)) 414 .addDef(HILOReg) 415 .add(I.getOperand(1)) 416 .add(I.getOperand(2)); 417 if (!constrainSelectedInstRegOperands(*PseudoDIV, TII, TRI, RBI)) 418 return false; 419 420 PseudoMove = BuildMI(MBB, I, I.getDebugLoc(), 421 TII.get(IsDiv ? Mips::PseudoMFLO : Mips::PseudoMFHI)) 422 .addDef(I.getOperand(0).getReg()) 423 .addUse(HILOReg); 424 if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI)) 425 return false; 426 427 I.eraseFromParent(); 428 return true; 429 } 430 case G_SELECT: { 431 // Handle operands with pointer type. 432 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MOVN_I_I)) 433 .add(I.getOperand(0)) 434 .add(I.getOperand(2)) 435 .add(I.getOperand(1)) 436 .add(I.getOperand(3)); 437 break; 438 } 439 case G_CONSTANT: { 440 MachineIRBuilder B(I); 441 if (!materialize32BitImm(I.getOperand(0).getReg(), 442 I.getOperand(1).getCImm()->getValue(), B)) 443 return false; 444 445 I.eraseFromParent(); 446 return true; 447 } 448 case G_FCONSTANT: { 449 const APFloat &FPimm = I.getOperand(1).getFPImm()->getValueAPF(); 450 APInt APImm = FPimm.bitcastToAPInt(); 451 unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits(); 452 453 if (Size == 32) { 454 Register GPRReg = MRI.createVirtualRegister(&Mips::GPR32RegClass); 455 MachineIRBuilder B(I); 456 if (!materialize32BitImm(GPRReg, APImm, B)) 457 return false; 458 459 MachineInstrBuilder MTC1 = 460 B.buildInstr(Mips::MTC1, {I.getOperand(0).getReg()}, {GPRReg}); 461 if (!MTC1.constrainAllUses(TII, TRI, RBI)) 462 return false; 463 } 464 if (Size == 64) { 465 Register GPRRegHigh = MRI.createVirtualRegister(&Mips::GPR32RegClass); 466 Register GPRRegLow = MRI.createVirtualRegister(&Mips::GPR32RegClass); 467 MachineIRBuilder B(I); 468 if (!materialize32BitImm(GPRRegHigh, APImm.getHiBits(32).trunc(32), B)) 469 return false; 470 if (!materialize32BitImm(GPRRegLow, APImm.getLoBits(32).trunc(32), B)) 471 return false; 472 473 MachineInstrBuilder PairF64 = B.buildInstr( 474 STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64, 475 {I.getOperand(0).getReg()}, {GPRRegLow, GPRRegHigh}); 476 if (!PairF64.constrainAllUses(TII, TRI, RBI)) 477 return false; 478 } 479 480 I.eraseFromParent(); 481 return true; 482 } 483 case G_FABS: { 484 unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits(); 485 unsigned FABSOpcode = 486 Size == 32 ? Mips::FABS_S 487 : STI.isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32; 488 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FABSOpcode)) 489 .add(I.getOperand(0)) 490 .add(I.getOperand(1)); 491 break; 492 } 493 case G_FPTOSI: { 494 unsigned FromSize = MRI.getType(I.getOperand(1).getReg()).getSizeInBits(); 495 unsigned ToSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits(); 496 (void)ToSize; 497 assert((ToSize == 32) && "Unsupported integer size for G_FPTOSI"); 498 assert((FromSize == 32 || FromSize == 64) && 499 "Unsupported floating point size for G_FPTOSI"); 500 501 unsigned Opcode; 502 if (FromSize == 32) 503 Opcode = Mips::TRUNC_W_S; 504 else 505 Opcode = STI.isFP64bit() ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32; 506 unsigned ResultInFPR = MRI.createVirtualRegister(&Mips::FGR32RegClass); 507 MachineInstr *Trunc = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode)) 508 .addDef(ResultInFPR) 509 .addUse(I.getOperand(1).getReg()); 510 if (!constrainSelectedInstRegOperands(*Trunc, TII, TRI, RBI)) 511 return false; 512 513 MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::MFC1)) 514 .addDef(I.getOperand(0).getReg()) 515 .addUse(ResultInFPR); 516 if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI)) 517 return false; 518 519 I.eraseFromParent(); 520 return true; 521 } 522 case G_GLOBAL_VALUE: { 523 const llvm::GlobalValue *GVal = I.getOperand(1).getGlobal(); 524 if (MF.getTarget().isPositionIndependent()) { 525 MachineInstr *LWGOT = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW)) 526 .addDef(I.getOperand(0).getReg()) 527 .addReg(MF.getInfo<MipsFunctionInfo>() 528 ->getGlobalBaseRegForGlobalISel()) 529 .addGlobalAddress(GVal); 530 // Global Values that don't have local linkage are handled differently 531 // when they are part of call sequence. MipsCallLowering::lowerCall 532 // creates G_GLOBAL_VALUE instruction as part of call sequence and adds 533 // MO_GOT_CALL flag when Callee doesn't have local linkage. 534 if (I.getOperand(1).getTargetFlags() == MipsII::MO_GOT_CALL) 535 LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT_CALL); 536 else 537 LWGOT->getOperand(2).setTargetFlags(MipsII::MO_GOT); 538 LWGOT->addMemOperand( 539 MF, MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF), 540 MachineMemOperand::MOLoad, 4, 4)); 541 if (!constrainSelectedInstRegOperands(*LWGOT, TII, TRI, RBI)) 542 return false; 543 544 if (GVal->hasLocalLinkage()) { 545 Register LWGOTDef = MRI.createVirtualRegister(&Mips::GPR32RegClass); 546 LWGOT->getOperand(0).setReg(LWGOTDef); 547 548 MachineInstr *ADDiu = 549 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) 550 .addDef(I.getOperand(0).getReg()) 551 .addReg(LWGOTDef) 552 .addGlobalAddress(GVal); 553 ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO); 554 if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI)) 555 return false; 556 } 557 } else { 558 Register LUiReg = MRI.createVirtualRegister(&Mips::GPR32RegClass); 559 560 MachineInstr *LUi = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi)) 561 .addDef(LUiReg) 562 .addGlobalAddress(GVal); 563 LUi->getOperand(1).setTargetFlags(MipsII::MO_ABS_HI); 564 if (!constrainSelectedInstRegOperands(*LUi, TII, TRI, RBI)) 565 return false; 566 567 MachineInstr *ADDiu = 568 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) 569 .addDef(I.getOperand(0).getReg()) 570 .addUse(LUiReg) 571 .addGlobalAddress(GVal); 572 ADDiu->getOperand(2).setTargetFlags(MipsII::MO_ABS_LO); 573 if (!constrainSelectedInstRegOperands(*ADDiu, TII, TRI, RBI)) 574 return false; 575 } 576 I.eraseFromParent(); 577 return true; 578 } 579 case G_JUMP_TABLE: { 580 if (MF.getTarget().isPositionIndependent()) { 581 MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LW)) 582 .addDef(I.getOperand(0).getReg()) 583 .addReg(MF.getInfo<MipsFunctionInfo>() 584 ->getGlobalBaseRegForGlobalISel()) 585 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_GOT) 586 .addMemOperand( 587 MF.getMachineMemOperand(MachinePointerInfo::getGOT(MF), 588 MachineMemOperand::MOLoad, 4, 4)); 589 } else { 590 MI = 591 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::LUi)) 592 .addDef(I.getOperand(0).getReg()) 593 .addJumpTableIndex(I.getOperand(1).getIndex(), MipsII::MO_ABS_HI); 594 } 595 break; 596 } 597 case G_ICMP: { 598 struct Instr { 599 unsigned Opcode; 600 Register Def, LHS, RHS; 601 Instr(unsigned Opcode, Register Def, Register LHS, Register RHS) 602 : Opcode(Opcode), Def(Def), LHS(LHS), RHS(RHS){}; 603 604 bool hasImm() const { 605 if (Opcode == Mips::SLTiu || Opcode == Mips::XORi) 606 return true; 607 return false; 608 } 609 }; 610 611 SmallVector<struct Instr, 2> Instructions; 612 Register ICMPReg = I.getOperand(0).getReg(); 613 Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass); 614 Register LHS = I.getOperand(2).getReg(); 615 Register RHS = I.getOperand(3).getReg(); 616 CmpInst::Predicate Cond = 617 static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate()); 618 619 switch (Cond) { 620 case CmpInst::ICMP_EQ: // LHS == RHS -> (LHS ^ RHS) < 1 621 Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS); 622 Instructions.emplace_back(Mips::SLTiu, ICMPReg, Temp, 1); 623 break; 624 case CmpInst::ICMP_NE: // LHS != RHS -> 0 < (LHS ^ RHS) 625 Instructions.emplace_back(Mips::XOR, Temp, LHS, RHS); 626 Instructions.emplace_back(Mips::SLTu, ICMPReg, Mips::ZERO, Temp); 627 break; 628 case CmpInst::ICMP_UGT: // LHS > RHS -> RHS < LHS 629 Instructions.emplace_back(Mips::SLTu, ICMPReg, RHS, LHS); 630 break; 631 case CmpInst::ICMP_UGE: // LHS >= RHS -> !(LHS < RHS) 632 Instructions.emplace_back(Mips::SLTu, Temp, LHS, RHS); 633 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1); 634 break; 635 case CmpInst::ICMP_ULT: // LHS < RHS -> LHS < RHS 636 Instructions.emplace_back(Mips::SLTu, ICMPReg, LHS, RHS); 637 break; 638 case CmpInst::ICMP_ULE: // LHS <= RHS -> !(RHS < LHS) 639 Instructions.emplace_back(Mips::SLTu, Temp, RHS, LHS); 640 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1); 641 break; 642 case CmpInst::ICMP_SGT: // LHS > RHS -> RHS < LHS 643 Instructions.emplace_back(Mips::SLT, ICMPReg, RHS, LHS); 644 break; 645 case CmpInst::ICMP_SGE: // LHS >= RHS -> !(LHS < RHS) 646 Instructions.emplace_back(Mips::SLT, Temp, LHS, RHS); 647 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1); 648 break; 649 case CmpInst::ICMP_SLT: // LHS < RHS -> LHS < RHS 650 Instructions.emplace_back(Mips::SLT, ICMPReg, LHS, RHS); 651 break; 652 case CmpInst::ICMP_SLE: // LHS <= RHS -> !(RHS < LHS) 653 Instructions.emplace_back(Mips::SLT, Temp, RHS, LHS); 654 Instructions.emplace_back(Mips::XORi, ICMPReg, Temp, 1); 655 break; 656 default: 657 return false; 658 } 659 660 MachineIRBuilder B(I); 661 for (const struct Instr &Instruction : Instructions) { 662 MachineInstrBuilder MIB = B.buildInstr( 663 Instruction.Opcode, {Instruction.Def}, {Instruction.LHS}); 664 665 if (Instruction.hasImm()) 666 MIB.addImm(Instruction.RHS); 667 else 668 MIB.addUse(Instruction.RHS); 669 670 if (!MIB.constrainAllUses(TII, TRI, RBI)) 671 return false; 672 } 673 674 I.eraseFromParent(); 675 return true; 676 } 677 case G_FCMP: { 678 unsigned MipsFCMPCondCode; 679 bool isLogicallyNegated; 680 switch (CmpInst::Predicate Cond = static_cast<CmpInst::Predicate>( 681 I.getOperand(1).getPredicate())) { 682 case CmpInst::FCMP_UNO: // Unordered 683 case CmpInst::FCMP_ORD: // Ordered (OR) 684 MipsFCMPCondCode = Mips::FCOND_UN; 685 isLogicallyNegated = Cond != CmpInst::FCMP_UNO; 686 break; 687 case CmpInst::FCMP_OEQ: // Equal 688 case CmpInst::FCMP_UNE: // Not Equal (NEQ) 689 MipsFCMPCondCode = Mips::FCOND_OEQ; 690 isLogicallyNegated = Cond != CmpInst::FCMP_OEQ; 691 break; 692 case CmpInst::FCMP_UEQ: // Unordered or Equal 693 case CmpInst::FCMP_ONE: // Ordered or Greater Than or Less Than (OGL) 694 MipsFCMPCondCode = Mips::FCOND_UEQ; 695 isLogicallyNegated = Cond != CmpInst::FCMP_UEQ; 696 break; 697 case CmpInst::FCMP_OLT: // Ordered or Less Than 698 case CmpInst::FCMP_UGE: // Unordered or Greater Than or Equal (UGE) 699 MipsFCMPCondCode = Mips::FCOND_OLT; 700 isLogicallyNegated = Cond != CmpInst::FCMP_OLT; 701 break; 702 case CmpInst::FCMP_ULT: // Unordered or Less Than 703 case CmpInst::FCMP_OGE: // Ordered or Greater Than or Equal (OGE) 704 MipsFCMPCondCode = Mips::FCOND_ULT; 705 isLogicallyNegated = Cond != CmpInst::FCMP_ULT; 706 break; 707 case CmpInst::FCMP_OLE: // Ordered or Less Than or Equal 708 case CmpInst::FCMP_UGT: // Unordered or Greater Than (UGT) 709 MipsFCMPCondCode = Mips::FCOND_OLE; 710 isLogicallyNegated = Cond != CmpInst::FCMP_OLE; 711 break; 712 case CmpInst::FCMP_ULE: // Unordered or Less Than or Equal 713 case CmpInst::FCMP_OGT: // Ordered or Greater Than (OGT) 714 MipsFCMPCondCode = Mips::FCOND_ULE; 715 isLogicallyNegated = Cond != CmpInst::FCMP_ULE; 716 break; 717 default: 718 return false; 719 } 720 721 // Default compare result in gpr register will be `true`. 722 // We will move `false` (MIPS::Zero) to gpr result when fcmp gives false 723 // using MOVF_I. When orignal predicate (Cond) is logically negated 724 // MipsFCMPCondCode, result is inverted i.e. MOVT_I is used. 725 unsigned MoveOpcode = isLogicallyNegated ? Mips::MOVT_I : Mips::MOVF_I; 726 727 unsigned TrueInReg = MRI.createVirtualRegister(&Mips::GPR32RegClass); 728 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::ADDiu)) 729 .addDef(TrueInReg) 730 .addUse(Mips::ZERO) 731 .addImm(1); 732 733 unsigned Size = MRI.getType(I.getOperand(2).getReg()).getSizeInBits(); 734 unsigned FCMPOpcode = 735 Size == 32 ? Mips::FCMP_S32 736 : STI.isFP64bit() ? Mips::FCMP_D64 : Mips::FCMP_D32; 737 MachineInstr *FCMP = BuildMI(MBB, I, I.getDebugLoc(), TII.get(FCMPOpcode)) 738 .addUse(I.getOperand(2).getReg()) 739 .addUse(I.getOperand(3).getReg()) 740 .addImm(MipsFCMPCondCode); 741 if (!constrainSelectedInstRegOperands(*FCMP, TII, TRI, RBI)) 742 return false; 743 744 MachineInstr *Move = BuildMI(MBB, I, I.getDebugLoc(), TII.get(MoveOpcode)) 745 .addDef(I.getOperand(0).getReg()) 746 .addUse(Mips::ZERO) 747 .addUse(Mips::FCC0) 748 .addUse(TrueInReg); 749 if (!constrainSelectedInstRegOperands(*Move, TII, TRI, RBI)) 750 return false; 751 752 I.eraseFromParent(); 753 return true; 754 } 755 default: 756 return false; 757 } 758 759 I.eraseFromParent(); 760 return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI); 761 } 762 763 namespace llvm { 764 InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &TM, 765 MipsSubtarget &Subtarget, 766 MipsRegisterBankInfo &RBI) { 767 return new MipsInstructionSelector(TM, Subtarget, RBI); 768 } 769 } // end namespace llvm 770