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