1 //===- ARMInstructionSelector.cpp ----------------------------*- C++ -*-==// 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 /// \file 10 /// This file implements the targeting of the InstructionSelector class for ARM. 11 /// \todo This should be generated by TableGen. 12 //===----------------------------------------------------------------------===// 13 14 #include "ARMRegisterBankInfo.h" 15 #include "ARMSubtarget.h" 16 #include "ARMTargetMachine.h" 17 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 18 #include "llvm/CodeGen/MachineConstantPool.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 #include "llvm/Support/Debug.h" 21 22 #define DEBUG_TYPE "arm-isel" 23 24 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" 25 26 using namespace llvm; 27 28 namespace { 29 30 #define GET_GLOBALISEL_PREDICATE_BITSET 31 #include "ARMGenGlobalISel.inc" 32 #undef GET_GLOBALISEL_PREDICATE_BITSET 33 34 class ARMInstructionSelector : public InstructionSelector { 35 public: 36 ARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI, 37 const ARMRegisterBankInfo &RBI); 38 39 bool select(MachineInstr &I) const override; 40 41 private: 42 bool selectImpl(MachineInstr &I) const; 43 44 struct CmpConstants; 45 struct InsertInfo; 46 47 bool selectCmp(CmpConstants Helper, MachineInstrBuilder &MIB, 48 MachineRegisterInfo &MRI) const; 49 50 // Helper for inserting a comparison sequence that sets \p ResReg to either 1 51 // if \p LHSReg and \p RHSReg are in the relationship defined by \p Cond, or 52 // \p PrevRes otherwise. In essence, it computes PrevRes OR (LHS Cond RHS). 53 bool insertComparison(CmpConstants Helper, InsertInfo I, unsigned ResReg, 54 ARMCC::CondCodes Cond, unsigned LHSReg, unsigned RHSReg, 55 unsigned PrevRes) const; 56 57 // Set \p DestReg to \p Constant. 58 void putConstant(InsertInfo I, unsigned DestReg, unsigned Constant) const; 59 60 bool selectGlobal(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const; 61 bool selectSelect(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const; 62 63 // Check if the types match and both operands have the expected size and 64 // register bank. 65 bool validOpRegPair(MachineRegisterInfo &MRI, unsigned LHS, unsigned RHS, 66 unsigned ExpectedSize, unsigned ExpectedRegBankID) const; 67 68 // Check if the register has the expected size and register bank. 69 bool validReg(MachineRegisterInfo &MRI, unsigned Reg, unsigned ExpectedSize, 70 unsigned ExpectedRegBankID) const; 71 72 const ARMBaseInstrInfo &TII; 73 const ARMBaseRegisterInfo &TRI; 74 const ARMBaseTargetMachine &TM; 75 const ARMRegisterBankInfo &RBI; 76 const ARMSubtarget &STI; 77 78 #define GET_GLOBALISEL_PREDICATES_DECL 79 #include "ARMGenGlobalISel.inc" 80 #undef GET_GLOBALISEL_PREDICATES_DECL 81 82 // We declare the temporaries used by selectImpl() in the class to minimize the 83 // cost of constructing placeholder values. 84 #define GET_GLOBALISEL_TEMPORARIES_DECL 85 #include "ARMGenGlobalISel.inc" 86 #undef GET_GLOBALISEL_TEMPORARIES_DECL 87 }; 88 } // end anonymous namespace 89 90 namespace llvm { 91 InstructionSelector * 92 createARMInstructionSelector(const ARMBaseTargetMachine &TM, 93 const ARMSubtarget &STI, 94 const ARMRegisterBankInfo &RBI) { 95 return new ARMInstructionSelector(TM, STI, RBI); 96 } 97 } 98 99 const unsigned zero_reg = 0; 100 101 #define GET_GLOBALISEL_IMPL 102 #include "ARMGenGlobalISel.inc" 103 #undef GET_GLOBALISEL_IMPL 104 105 ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM, 106 const ARMSubtarget &STI, 107 const ARMRegisterBankInfo &RBI) 108 : InstructionSelector(), TII(*STI.getInstrInfo()), 109 TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI), STI(STI), 110 #define GET_GLOBALISEL_PREDICATES_INIT 111 #include "ARMGenGlobalISel.inc" 112 #undef GET_GLOBALISEL_PREDICATES_INIT 113 #define GET_GLOBALISEL_TEMPORARIES_INIT 114 #include "ARMGenGlobalISel.inc" 115 #undef GET_GLOBALISEL_TEMPORARIES_INIT 116 { 117 } 118 119 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, 120 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, 121 const RegisterBankInfo &RBI) { 122 unsigned DstReg = I.getOperand(0).getReg(); 123 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) 124 return true; 125 126 const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI); 127 (void)RegBank; 128 assert(RegBank && "Can't get reg bank for virtual register"); 129 130 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); 131 assert((RegBank->getID() == ARM::GPRRegBankID || 132 RegBank->getID() == ARM::FPRRegBankID) && 133 "Unsupported reg bank"); 134 135 const TargetRegisterClass *RC = &ARM::GPRRegClass; 136 137 if (RegBank->getID() == ARM::FPRRegBankID) { 138 if (DstSize == 32) 139 RC = &ARM::SPRRegClass; 140 else if (DstSize == 64) 141 RC = &ARM::DPRRegClass; 142 else 143 llvm_unreachable("Unsupported destination size"); 144 } 145 146 // No need to constrain SrcReg. It will get constrained when 147 // we hit another of its uses or its defs. 148 // Copies do not have constraints. 149 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { 150 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 151 << " operand\n"); 152 return false; 153 } 154 return true; 155 } 156 157 static bool selectMergeValues(MachineInstrBuilder &MIB, 158 const ARMBaseInstrInfo &TII, 159 MachineRegisterInfo &MRI, 160 const TargetRegisterInfo &TRI, 161 const RegisterBankInfo &RBI) { 162 assert(TII.getSubtarget().hasVFP2() && "Can't select merge without VFP"); 163 164 // We only support G_MERGE_VALUES as a way to stick together two scalar GPRs 165 // into one DPR. 166 unsigned VReg0 = MIB->getOperand(0).getReg(); 167 (void)VReg0; 168 assert(MRI.getType(VReg0).getSizeInBits() == 64 && 169 RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID && 170 "Unsupported operand for G_MERGE_VALUES"); 171 unsigned VReg1 = MIB->getOperand(1).getReg(); 172 (void)VReg1; 173 assert(MRI.getType(VReg1).getSizeInBits() == 32 && 174 RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID && 175 "Unsupported operand for G_MERGE_VALUES"); 176 unsigned VReg2 = MIB->getOperand(2).getReg(); 177 (void)VReg2; 178 assert(MRI.getType(VReg2).getSizeInBits() == 32 && 179 RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID && 180 "Unsupported operand for G_MERGE_VALUES"); 181 182 MIB->setDesc(TII.get(ARM::VMOVDRR)); 183 MIB.add(predOps(ARMCC::AL)); 184 185 return true; 186 } 187 188 static bool selectUnmergeValues(MachineInstrBuilder &MIB, 189 const ARMBaseInstrInfo &TII, 190 MachineRegisterInfo &MRI, 191 const TargetRegisterInfo &TRI, 192 const RegisterBankInfo &RBI) { 193 assert(TII.getSubtarget().hasVFP2() && "Can't select unmerge without VFP"); 194 195 // We only support G_UNMERGE_VALUES as a way to break up one DPR into two 196 // GPRs. 197 unsigned VReg0 = MIB->getOperand(0).getReg(); 198 (void)VReg0; 199 assert(MRI.getType(VReg0).getSizeInBits() == 32 && 200 RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID && 201 "Unsupported operand for G_UNMERGE_VALUES"); 202 unsigned VReg1 = MIB->getOperand(1).getReg(); 203 (void)VReg1; 204 assert(MRI.getType(VReg1).getSizeInBits() == 32 && 205 RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID && 206 "Unsupported operand for G_UNMERGE_VALUES"); 207 unsigned VReg2 = MIB->getOperand(2).getReg(); 208 (void)VReg2; 209 assert(MRI.getType(VReg2).getSizeInBits() == 64 && 210 RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID && 211 "Unsupported operand for G_UNMERGE_VALUES"); 212 213 MIB->setDesc(TII.get(ARM::VMOVRRD)); 214 MIB.add(predOps(ARMCC::AL)); 215 216 return true; 217 } 218 219 /// Select the opcode for simple extensions (that translate to a single SXT/UXT 220 /// instruction). Extension operations more complicated than that should not 221 /// invoke this. Returns the original opcode if it doesn't know how to select a 222 /// better one. 223 static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) { 224 using namespace TargetOpcode; 225 226 if (Size != 8 && Size != 16) 227 return Opc; 228 229 if (Opc == G_SEXT) 230 return Size == 8 ? ARM::SXTB : ARM::SXTH; 231 232 if (Opc == G_ZEXT) 233 return Size == 8 ? ARM::UXTB : ARM::UXTH; 234 235 return Opc; 236 } 237 238 /// Select the opcode for simple loads and stores. For types smaller than 32 239 /// bits, the value will be zero extended. Returns the original opcode if it 240 /// doesn't know how to select a better one. 241 static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank, 242 unsigned Size) { 243 bool isStore = Opc == TargetOpcode::G_STORE; 244 245 if (RegBank == ARM::GPRRegBankID) { 246 switch (Size) { 247 case 1: 248 case 8: 249 return isStore ? ARM::STRBi12 : ARM::LDRBi12; 250 case 16: 251 return isStore ? ARM::STRH : ARM::LDRH; 252 case 32: 253 return isStore ? ARM::STRi12 : ARM::LDRi12; 254 default: 255 return Opc; 256 } 257 } 258 259 if (RegBank == ARM::FPRRegBankID) { 260 switch (Size) { 261 case 32: 262 return isStore ? ARM::VSTRS : ARM::VLDRS; 263 case 64: 264 return isStore ? ARM::VSTRD : ARM::VLDRD; 265 default: 266 return Opc; 267 } 268 } 269 270 return Opc; 271 } 272 273 // When lowering comparisons, we sometimes need to perform two compares instead 274 // of just one. Get the condition codes for both comparisons. If only one is 275 // needed, the second member of the pair is ARMCC::AL. 276 static std::pair<ARMCC::CondCodes, ARMCC::CondCodes> 277 getComparePreds(CmpInst::Predicate Pred) { 278 std::pair<ARMCC::CondCodes, ARMCC::CondCodes> Preds = {ARMCC::AL, ARMCC::AL}; 279 switch (Pred) { 280 case CmpInst::FCMP_ONE: 281 Preds = {ARMCC::GT, ARMCC::MI}; 282 break; 283 case CmpInst::FCMP_UEQ: 284 Preds = {ARMCC::EQ, ARMCC::VS}; 285 break; 286 case CmpInst::ICMP_EQ: 287 case CmpInst::FCMP_OEQ: 288 Preds.first = ARMCC::EQ; 289 break; 290 case CmpInst::ICMP_SGT: 291 case CmpInst::FCMP_OGT: 292 Preds.first = ARMCC::GT; 293 break; 294 case CmpInst::ICMP_SGE: 295 case CmpInst::FCMP_OGE: 296 Preds.first = ARMCC::GE; 297 break; 298 case CmpInst::ICMP_UGT: 299 case CmpInst::FCMP_UGT: 300 Preds.first = ARMCC::HI; 301 break; 302 case CmpInst::FCMP_OLT: 303 Preds.first = ARMCC::MI; 304 break; 305 case CmpInst::ICMP_ULE: 306 case CmpInst::FCMP_OLE: 307 Preds.first = ARMCC::LS; 308 break; 309 case CmpInst::FCMP_ORD: 310 Preds.first = ARMCC::VC; 311 break; 312 case CmpInst::FCMP_UNO: 313 Preds.first = ARMCC::VS; 314 break; 315 case CmpInst::FCMP_UGE: 316 Preds.first = ARMCC::PL; 317 break; 318 case CmpInst::ICMP_SLT: 319 case CmpInst::FCMP_ULT: 320 Preds.first = ARMCC::LT; 321 break; 322 case CmpInst::ICMP_SLE: 323 case CmpInst::FCMP_ULE: 324 Preds.first = ARMCC::LE; 325 break; 326 case CmpInst::FCMP_UNE: 327 case CmpInst::ICMP_NE: 328 Preds.first = ARMCC::NE; 329 break; 330 case CmpInst::ICMP_UGE: 331 Preds.first = ARMCC::HS; 332 break; 333 case CmpInst::ICMP_ULT: 334 Preds.first = ARMCC::LO; 335 break; 336 default: 337 break; 338 } 339 assert(Preds.first != ARMCC::AL && "No comparisons needed?"); 340 return Preds; 341 } 342 343 struct ARMInstructionSelector::CmpConstants { 344 CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned OpRegBank, 345 unsigned OpSize) 346 : ComparisonOpcode(CmpOpcode), ReadFlagsOpcode(FlagsOpcode), 347 OperandRegBankID(OpRegBank), OperandSize(OpSize) {} 348 349 // The opcode used for performing the comparison. 350 const unsigned ComparisonOpcode; 351 352 // The opcode used for reading the flags set by the comparison. May be 353 // ARM::INSTRUCTION_LIST_END if we don't need to read the flags. 354 const unsigned ReadFlagsOpcode; 355 356 // The assumed register bank ID for the operands. 357 const unsigned OperandRegBankID; 358 359 // The assumed size in bits for the operands. 360 const unsigned OperandSize; 361 }; 362 363 struct ARMInstructionSelector::InsertInfo { 364 InsertInfo(MachineInstrBuilder &MIB) 365 : MBB(*MIB->getParent()), InsertBefore(std::next(MIB->getIterator())), 366 DbgLoc(MIB->getDebugLoc()) {} 367 368 MachineBasicBlock &MBB; 369 const MachineBasicBlock::instr_iterator InsertBefore; 370 const DebugLoc &DbgLoc; 371 }; 372 373 void ARMInstructionSelector::putConstant(InsertInfo I, unsigned DestReg, 374 unsigned Constant) const { 375 (void)BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(ARM::MOVi)) 376 .addDef(DestReg) 377 .addImm(Constant) 378 .add(predOps(ARMCC::AL)) 379 .add(condCodeOp()); 380 } 381 382 bool ARMInstructionSelector::validOpRegPair(MachineRegisterInfo &MRI, 383 unsigned LHSReg, unsigned RHSReg, 384 unsigned ExpectedSize, 385 unsigned ExpectedRegBankID) const { 386 return MRI.getType(LHSReg) == MRI.getType(RHSReg) && 387 validReg(MRI, LHSReg, ExpectedSize, ExpectedRegBankID) && 388 validReg(MRI, RHSReg, ExpectedSize, ExpectedRegBankID); 389 } 390 391 bool ARMInstructionSelector::validReg(MachineRegisterInfo &MRI, unsigned Reg, 392 unsigned ExpectedSize, 393 unsigned ExpectedRegBankID) const { 394 if (MRI.getType(Reg).getSizeInBits() != ExpectedSize) { 395 DEBUG(dbgs() << "Unexpected size for register"); 396 return false; 397 } 398 399 if (RBI.getRegBank(Reg, MRI, TRI)->getID() != ExpectedRegBankID) { 400 DEBUG(dbgs() << "Unexpected register bank for register"); 401 return false; 402 } 403 404 return true; 405 } 406 407 bool ARMInstructionSelector::selectCmp(CmpConstants Helper, 408 MachineInstrBuilder &MIB, 409 MachineRegisterInfo &MRI) const { 410 const InsertInfo I(MIB); 411 412 auto ResReg = MIB->getOperand(0).getReg(); 413 if (!validReg(MRI, ResReg, 1, ARM::GPRRegBankID)) 414 return false; 415 416 auto Cond = 417 static_cast<CmpInst::Predicate>(MIB->getOperand(1).getPredicate()); 418 if (Cond == CmpInst::FCMP_TRUE || Cond == CmpInst::FCMP_FALSE) { 419 putConstant(I, ResReg, Cond == CmpInst::FCMP_TRUE ? 1 : 0); 420 MIB->eraseFromParent(); 421 return true; 422 } 423 424 auto LHSReg = MIB->getOperand(2).getReg(); 425 auto RHSReg = MIB->getOperand(3).getReg(); 426 if (!validOpRegPair(MRI, LHSReg, RHSReg, Helper.OperandSize, 427 Helper.OperandRegBankID)) 428 return false; 429 430 auto ARMConds = getComparePreds(Cond); 431 auto ZeroReg = MRI.createVirtualRegister(&ARM::GPRRegClass); 432 putConstant(I, ZeroReg, 0); 433 434 if (ARMConds.second == ARMCC::AL) { 435 // Simple case, we only need one comparison and we're done. 436 if (!insertComparison(Helper, I, ResReg, ARMConds.first, LHSReg, RHSReg, 437 ZeroReg)) 438 return false; 439 } else { 440 // Not so simple, we need two successive comparisons. 441 auto IntermediateRes = MRI.createVirtualRegister(&ARM::GPRRegClass); 442 if (!insertComparison(Helper, I, IntermediateRes, ARMConds.first, LHSReg, 443 RHSReg, ZeroReg)) 444 return false; 445 if (!insertComparison(Helper, I, ResReg, ARMConds.second, LHSReg, RHSReg, 446 IntermediateRes)) 447 return false; 448 } 449 450 MIB->eraseFromParent(); 451 return true; 452 } 453 454 bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo I, 455 unsigned ResReg, 456 ARMCC::CondCodes Cond, 457 unsigned LHSReg, unsigned RHSReg, 458 unsigned PrevRes) const { 459 // Perform the comparison. 460 auto CmpI = 461 BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(Helper.ComparisonOpcode)) 462 .addUse(LHSReg) 463 .addUse(RHSReg) 464 .add(predOps(ARMCC::AL)); 465 if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI)) 466 return false; 467 468 // Read the comparison flags (if necessary). 469 if (Helper.ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) { 470 auto ReadI = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, 471 TII.get(Helper.ReadFlagsOpcode)) 472 .add(predOps(ARMCC::AL)); 473 if (!constrainSelectedInstRegOperands(*ReadI, TII, TRI, RBI)) 474 return false; 475 } 476 477 // Select either 1 or the previous result based on the value of the flags. 478 auto Mov1I = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(ARM::MOVCCi)) 479 .addDef(ResReg) 480 .addUse(PrevRes) 481 .addImm(1) 482 .add(predOps(Cond, ARM::CPSR)); 483 if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI)) 484 return false; 485 486 return true; 487 } 488 489 bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB, 490 MachineRegisterInfo &MRI) const { 491 if ((STI.isROPI() || STI.isRWPI()) && !STI.isTargetELF()) { 492 DEBUG(dbgs() << "ROPI and RWPI only supported for ELF\n"); 493 return false; 494 } 495 496 auto GV = MIB->getOperand(1).getGlobal(); 497 if (GV->isThreadLocal()) { 498 DEBUG(dbgs() << "TLS variables not supported yet\n"); 499 return false; 500 } 501 502 auto &MBB = *MIB->getParent(); 503 auto &MF = *MBB.getParent(); 504 505 bool UseMovt = STI.useMovt(MF); 506 507 unsigned Size = TM.getPointerSize(); 508 unsigned Alignment = 4; 509 510 auto addOpsForConstantPoolLoad = [&MF, Alignment, 511 Size](MachineInstrBuilder &MIB, 512 const GlobalValue *GV, bool IsSBREL) { 513 assert(MIB->getOpcode() == ARM::LDRi12 && "Unsupported instruction"); 514 auto ConstPool = MF.getConstantPool(); 515 auto CPIndex = 516 // For SB relative entries we need a target-specific constant pool. 517 // Otherwise, just use a regular constant pool entry. 518 IsSBREL 519 ? ConstPool->getConstantPoolIndex( 520 ARMConstantPoolConstant::Create(GV, ARMCP::SBREL), Alignment) 521 : ConstPool->getConstantPoolIndex(GV, Alignment); 522 MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0) 523 .addMemOperand( 524 MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF), 525 MachineMemOperand::MOLoad, Size, Alignment)) 526 .addImm(0) 527 .add(predOps(ARMCC::AL)); 528 }; 529 530 if (TM.isPositionIndependent()) { 531 bool Indirect = STI.isGVIndirectSymbol(GV); 532 // FIXME: Taking advantage of MOVT for ELF is pretty involved, so we don't 533 // support it yet. See PR28229. 534 unsigned Opc = 535 UseMovt && !STI.isTargetELF() 536 ? (Indirect ? ARM::MOV_ga_pcrel_ldr : ARM::MOV_ga_pcrel) 537 : (Indirect ? ARM::LDRLIT_ga_pcrel_ldr : ARM::LDRLIT_ga_pcrel); 538 MIB->setDesc(TII.get(Opc)); 539 540 if (STI.isTargetDarwin()) 541 MIB->getOperand(1).setTargetFlags(ARMII::MO_NONLAZY); 542 543 if (Indirect) 544 MIB.addMemOperand(MF.getMachineMemOperand( 545 MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad, 546 TM.getPointerSize(), Alignment)); 547 548 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); 549 } 550 551 bool isReadOnly = STI.getTargetLowering()->isReadOnly(GV); 552 if (STI.isROPI() && isReadOnly) { 553 unsigned Opc = UseMovt ? ARM::MOV_ga_pcrel : ARM::LDRLIT_ga_pcrel; 554 MIB->setDesc(TII.get(Opc)); 555 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); 556 } 557 if (STI.isRWPI() && !isReadOnly) { 558 auto Offset = MRI.createVirtualRegister(&ARM::GPRRegClass); 559 MachineInstrBuilder OffsetMIB; 560 if (UseMovt) { 561 OffsetMIB = BuildMI(MBB, *MIB, MIB->getDebugLoc(), 562 TII.get(ARM::MOVi32imm), Offset); 563 OffsetMIB.addGlobalAddress(GV, /*Offset*/ 0, ARMII::MO_SBREL); 564 } else { 565 // Load the offset from the constant pool. 566 OffsetMIB = 567 BuildMI(MBB, *MIB, MIB->getDebugLoc(), TII.get(ARM::LDRi12), Offset); 568 addOpsForConstantPoolLoad(OffsetMIB, GV, /*IsSBREL*/ true); 569 } 570 if (!constrainSelectedInstRegOperands(*OffsetMIB, TII, TRI, RBI)) 571 return false; 572 573 // Add the offset to the SB register. 574 MIB->setDesc(TII.get(ARM::ADDrr)); 575 MIB->RemoveOperand(1); 576 MIB.addReg(ARM::R9) // FIXME: don't hardcode R9 577 .addReg(Offset) 578 .add(predOps(ARMCC::AL)) 579 .add(condCodeOp()); 580 581 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); 582 } 583 584 if (STI.isTargetELF()) { 585 if (UseMovt) { 586 MIB->setDesc(TII.get(ARM::MOVi32imm)); 587 } else { 588 // Load the global's address from the constant pool. 589 MIB->setDesc(TII.get(ARM::LDRi12)); 590 MIB->RemoveOperand(1); 591 addOpsForConstantPoolLoad(MIB, GV, /*IsSBREL*/ false); 592 } 593 } else if (STI.isTargetMachO()) { 594 if (UseMovt) 595 MIB->setDesc(TII.get(ARM::MOVi32imm)); 596 else 597 MIB->setDesc(TII.get(ARM::LDRLIT_ga_abs)); 598 } else { 599 DEBUG(dbgs() << "Object format not supported yet\n"); 600 return false; 601 } 602 603 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); 604 } 605 606 bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB, 607 MachineRegisterInfo &MRI) const { 608 auto &MBB = *MIB->getParent(); 609 auto InsertBefore = std::next(MIB->getIterator()); 610 auto &DbgLoc = MIB->getDebugLoc(); 611 612 // Compare the condition to 0. 613 auto CondReg = MIB->getOperand(1).getReg(); 614 assert(validReg(MRI, CondReg, 1, ARM::GPRRegBankID) && 615 "Unsupported types for select operation"); 616 auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::CMPri)) 617 .addUse(CondReg) 618 .addImm(0) 619 .add(predOps(ARMCC::AL)); 620 if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI)) 621 return false; 622 623 // Move a value into the result register based on the result of the 624 // comparison. 625 auto ResReg = MIB->getOperand(0).getReg(); 626 auto TrueReg = MIB->getOperand(2).getReg(); 627 auto FalseReg = MIB->getOperand(3).getReg(); 628 assert(validOpRegPair(MRI, ResReg, TrueReg, 32, ARM::GPRRegBankID) && 629 validOpRegPair(MRI, TrueReg, FalseReg, 32, ARM::GPRRegBankID) && 630 "Unsupported types for select operation"); 631 auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVCCr)) 632 .addDef(ResReg) 633 .addUse(TrueReg) 634 .addUse(FalseReg) 635 .add(predOps(ARMCC::EQ, ARM::CPSR)); 636 if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI)) 637 return false; 638 639 MIB->eraseFromParent(); 640 return true; 641 } 642 643 bool ARMInstructionSelector::select(MachineInstr &I) const { 644 assert(I.getParent() && "Instruction should be in a basic block!"); 645 assert(I.getParent()->getParent() && "Instruction should be in a function!"); 646 647 auto &MBB = *I.getParent(); 648 auto &MF = *MBB.getParent(); 649 auto &MRI = MF.getRegInfo(); 650 651 if (!isPreISelGenericOpcode(I.getOpcode())) { 652 if (I.isCopy()) 653 return selectCopy(I, TII, MRI, TRI, RBI); 654 655 return true; 656 } 657 658 if (selectImpl(I)) 659 return true; 660 661 MachineInstrBuilder MIB{MF, I}; 662 bool isSExt = false; 663 664 using namespace TargetOpcode; 665 switch (I.getOpcode()) { 666 case G_SEXT: 667 isSExt = true; 668 LLVM_FALLTHROUGH; 669 case G_ZEXT: { 670 LLT DstTy = MRI.getType(I.getOperand(0).getReg()); 671 // FIXME: Smaller destination sizes coming soon! 672 if (DstTy.getSizeInBits() != 32) { 673 DEBUG(dbgs() << "Unsupported destination size for extension"); 674 return false; 675 } 676 677 LLT SrcTy = MRI.getType(I.getOperand(1).getReg()); 678 unsigned SrcSize = SrcTy.getSizeInBits(); 679 switch (SrcSize) { 680 case 1: { 681 // ZExt boils down to & 0x1; for SExt we also subtract that from 0 682 I.setDesc(TII.get(ARM::ANDri)); 683 MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp()); 684 685 if (isSExt) { 686 unsigned SExtResult = I.getOperand(0).getReg(); 687 688 // Use a new virtual register for the result of the AND 689 unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass); 690 I.getOperand(0).setReg(AndResult); 691 692 auto InsertBefore = std::next(I.getIterator()); 693 auto SubI = 694 BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri)) 695 .addDef(SExtResult) 696 .addUse(AndResult) 697 .addImm(0) 698 .add(predOps(ARMCC::AL)) 699 .add(condCodeOp()); 700 if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI)) 701 return false; 702 } 703 break; 704 } 705 case 8: 706 case 16: { 707 unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize); 708 if (NewOpc == I.getOpcode()) 709 return false; 710 I.setDesc(TII.get(NewOpc)); 711 MIB.addImm(0).add(predOps(ARMCC::AL)); 712 break; 713 } 714 default: 715 DEBUG(dbgs() << "Unsupported source size for extension"); 716 return false; 717 } 718 break; 719 } 720 case G_ANYEXT: 721 case G_TRUNC: { 722 // The high bits are undefined, so there's nothing special to do, just 723 // treat it as a copy. 724 auto SrcReg = I.getOperand(1).getReg(); 725 auto DstReg = I.getOperand(0).getReg(); 726 727 const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI); 728 const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI); 729 730 if (SrcRegBank.getID() != DstRegBank.getID()) { 731 DEBUG(dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n"); 732 return false; 733 } 734 735 if (SrcRegBank.getID() != ARM::GPRRegBankID) { 736 DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n"); 737 return false; 738 } 739 740 I.setDesc(TII.get(COPY)); 741 return selectCopy(I, TII, MRI, TRI, RBI); 742 } 743 case G_SELECT: 744 return selectSelect(MIB, MRI); 745 case G_ICMP: { 746 CmpConstants Helper(ARM::CMPrr, ARM::INSTRUCTION_LIST_END, 747 ARM::GPRRegBankID, 32); 748 return selectCmp(Helper, MIB, MRI); 749 } 750 case G_FCMP: { 751 assert(STI.hasVFP2() && "Can't select fcmp without VFP"); 752 753 unsigned OpReg = I.getOperand(2).getReg(); 754 unsigned Size = MRI.getType(OpReg).getSizeInBits(); 755 756 if (Size == 64 && STI.isFPOnlySP()) { 757 DEBUG(dbgs() << "Subtarget only supports single precision"); 758 return false; 759 } 760 if (Size != 32 && Size != 64) { 761 DEBUG(dbgs() << "Unsupported size for G_FCMP operand"); 762 return false; 763 } 764 765 CmpConstants Helper(Size == 32 ? ARM::VCMPS : ARM::VCMPD, ARM::FMSTAT, 766 ARM::FPRRegBankID, Size); 767 return selectCmp(Helper, MIB, MRI); 768 } 769 case G_GEP: 770 I.setDesc(TII.get(ARM::ADDrr)); 771 MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); 772 break; 773 case G_FRAME_INDEX: 774 // Add 0 to the given frame index and hope it will eventually be folded into 775 // the user(s). 776 I.setDesc(TII.get(ARM::ADDri)); 777 MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp()); 778 break; 779 case G_CONSTANT: { 780 unsigned Reg = I.getOperand(0).getReg(); 781 782 if (!validReg(MRI, Reg, 32, ARM::GPRRegBankID)) 783 return false; 784 785 I.setDesc(TII.get(ARM::MOVi)); 786 MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); 787 788 auto &Val = I.getOperand(1); 789 if (Val.isCImm()) { 790 if (Val.getCImm()->getBitWidth() > 32) 791 return false; 792 Val.ChangeToImmediate(Val.getCImm()->getZExtValue()); 793 } 794 795 if (!Val.isImm()) { 796 return false; 797 } 798 799 break; 800 } 801 case G_GLOBAL_VALUE: 802 return selectGlobal(MIB, MRI); 803 case G_STORE: 804 case G_LOAD: { 805 const auto &MemOp = **I.memoperands_begin(); 806 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { 807 DEBUG(dbgs() << "Atomic load/store not supported yet\n"); 808 return false; 809 } 810 811 unsigned Reg = I.getOperand(0).getReg(); 812 unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID(); 813 814 LLT ValTy = MRI.getType(Reg); 815 const auto ValSize = ValTy.getSizeInBits(); 816 817 assert((ValSize != 64 || STI.hasVFP2()) && 818 "Don't know how to load/store 64-bit value without VFP"); 819 820 const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize); 821 if (NewOpc == G_LOAD || NewOpc == G_STORE) 822 return false; 823 824 I.setDesc(TII.get(NewOpc)); 825 826 if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH) 827 // LDRH has a funny addressing mode (there's already a FIXME for it). 828 MIB.addReg(0); 829 MIB.addImm(0).add(predOps(ARMCC::AL)); 830 break; 831 } 832 case G_MERGE_VALUES: { 833 if (!selectMergeValues(MIB, TII, MRI, TRI, RBI)) 834 return false; 835 break; 836 } 837 case G_UNMERGE_VALUES: { 838 if (!selectUnmergeValues(MIB, TII, MRI, TRI, RBI)) 839 return false; 840 break; 841 } 842 case G_BRCOND: { 843 if (!validReg(MRI, I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) { 844 DEBUG(dbgs() << "Unsupported condition register for G_BRCOND"); 845 return false; 846 } 847 848 // Set the flags. 849 auto Test = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ARM::TSTri)) 850 .addReg(I.getOperand(0).getReg()) 851 .addImm(1) 852 .add(predOps(ARMCC::AL)); 853 if (!constrainSelectedInstRegOperands(*Test, TII, TRI, RBI)) 854 return false; 855 856 // Branch conditionally. 857 auto Branch = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ARM::Bcc)) 858 .add(I.getOperand(1)) 859 .add(predOps(ARMCC::EQ, ARM::CPSR)); 860 if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI)) 861 return false; 862 I.eraseFromParent(); 863 return true; 864 } 865 default: 866 return false; 867 } 868 869 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 870 } 871