1 //===- AArch64InstructionSelector.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 11 /// AArch64. 12 /// \todo This should be generated by TableGen. 13 //===----------------------------------------------------------------------===// 14 15 #include "AArch64InstrInfo.h" 16 #include "AArch64MachineFunctionInfo.h" 17 #include "AArch64RegisterBankInfo.h" 18 #include "AArch64RegisterInfo.h" 19 #include "AArch64Subtarget.h" 20 #include "AArch64TargetMachine.h" 21 #include "MCTargetDesc/AArch64AddressingModes.h" 22 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 23 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" 24 #include "llvm/CodeGen/GlobalISel/Utils.h" 25 #include "llvm/CodeGen/MachineBasicBlock.h" 26 #include "llvm/CodeGen/MachineFunction.h" 27 #include "llvm/CodeGen/MachineInstr.h" 28 #include "llvm/CodeGen/MachineInstrBuilder.h" 29 #include "llvm/CodeGen/MachineOperand.h" 30 #include "llvm/CodeGen/MachineRegisterInfo.h" 31 #include "llvm/IR/Type.h" 32 #include "llvm/Support/Debug.h" 33 #include "llvm/Support/raw_ostream.h" 34 35 #define DEBUG_TYPE "aarch64-isel" 36 37 using namespace llvm; 38 39 namespace { 40 41 #define GET_GLOBALISEL_PREDICATE_BITSET 42 #include "AArch64GenGlobalISel.inc" 43 #undef GET_GLOBALISEL_PREDICATE_BITSET 44 45 class AArch64InstructionSelector : public InstructionSelector { 46 public: 47 AArch64InstructionSelector(const AArch64TargetMachine &TM, 48 const AArch64Subtarget &STI, 49 const AArch64RegisterBankInfo &RBI); 50 51 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override; 52 static const char *getName() { return DEBUG_TYPE; } 53 54 private: 55 /// tblgen-erated 'select' implementation, used as the initial selector for 56 /// the patterns that don't require complex C++. 57 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; 58 59 bool selectVaStartAAPCS(MachineInstr &I, MachineFunction &MF, 60 MachineRegisterInfo &MRI) const; 61 bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF, 62 MachineRegisterInfo &MRI) const; 63 64 bool selectCompareBranch(MachineInstr &I, MachineFunction &MF, 65 MachineRegisterInfo &MRI) const; 66 67 ComplexRendererFns selectArithImmed(MachineOperand &Root) const; 68 69 ComplexRendererFns selectAddrModeUnscaled(MachineOperand &Root, 70 unsigned Size) const; 71 72 ComplexRendererFns selectAddrModeUnscaled8(MachineOperand &Root) const { 73 return selectAddrModeUnscaled(Root, 1); 74 } 75 ComplexRendererFns selectAddrModeUnscaled16(MachineOperand &Root) const { 76 return selectAddrModeUnscaled(Root, 2); 77 } 78 ComplexRendererFns selectAddrModeUnscaled32(MachineOperand &Root) const { 79 return selectAddrModeUnscaled(Root, 4); 80 } 81 ComplexRendererFns selectAddrModeUnscaled64(MachineOperand &Root) const { 82 return selectAddrModeUnscaled(Root, 8); 83 } 84 ComplexRendererFns selectAddrModeUnscaled128(MachineOperand &Root) const { 85 return selectAddrModeUnscaled(Root, 16); 86 } 87 88 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root, 89 unsigned Size) const; 90 template <int Width> 91 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root) const { 92 return selectAddrModeIndexed(Root, Width / 8); 93 } 94 95 const AArch64TargetMachine &TM; 96 const AArch64Subtarget &STI; 97 const AArch64InstrInfo &TII; 98 const AArch64RegisterInfo &TRI; 99 const AArch64RegisterBankInfo &RBI; 100 101 #define GET_GLOBALISEL_PREDICATES_DECL 102 #include "AArch64GenGlobalISel.inc" 103 #undef GET_GLOBALISEL_PREDICATES_DECL 104 105 // We declare the temporaries used by selectImpl() in the class to minimize the 106 // cost of constructing placeholder values. 107 #define GET_GLOBALISEL_TEMPORARIES_DECL 108 #include "AArch64GenGlobalISel.inc" 109 #undef GET_GLOBALISEL_TEMPORARIES_DECL 110 }; 111 112 } // end anonymous namespace 113 114 #define GET_GLOBALISEL_IMPL 115 #include "AArch64GenGlobalISel.inc" 116 #undef GET_GLOBALISEL_IMPL 117 118 AArch64InstructionSelector::AArch64InstructionSelector( 119 const AArch64TargetMachine &TM, const AArch64Subtarget &STI, 120 const AArch64RegisterBankInfo &RBI) 121 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), 122 TRI(*STI.getRegisterInfo()), RBI(RBI), 123 #define GET_GLOBALISEL_PREDICATES_INIT 124 #include "AArch64GenGlobalISel.inc" 125 #undef GET_GLOBALISEL_PREDICATES_INIT 126 #define GET_GLOBALISEL_TEMPORARIES_INIT 127 #include "AArch64GenGlobalISel.inc" 128 #undef GET_GLOBALISEL_TEMPORARIES_INIT 129 { 130 } 131 132 // FIXME: This should be target-independent, inferred from the types declared 133 // for each class in the bank. 134 static const TargetRegisterClass * 135 getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB, 136 const RegisterBankInfo &RBI) { 137 if (RB.getID() == AArch64::GPRRegBankID) { 138 if (Ty.getSizeInBits() <= 32) 139 return &AArch64::GPR32RegClass; 140 if (Ty.getSizeInBits() == 64) 141 return &AArch64::GPR64RegClass; 142 return nullptr; 143 } 144 145 if (RB.getID() == AArch64::FPRRegBankID) { 146 if (Ty.getSizeInBits() == 32) 147 return &AArch64::FPR32RegClass; 148 if (Ty.getSizeInBits() == 64) 149 return &AArch64::FPR64RegClass; 150 if (Ty.getSizeInBits() == 128) 151 return &AArch64::FPR128RegClass; 152 return nullptr; 153 } 154 155 return nullptr; 156 } 157 158 /// Check whether \p I is a currently unsupported binary operation: 159 /// - it has an unsized type 160 /// - an operand is not a vreg 161 /// - all operands are not in the same bank 162 /// These are checks that should someday live in the verifier, but right now, 163 /// these are mostly limitations of the aarch64 selector. 164 static bool unsupportedBinOp(const MachineInstr &I, 165 const AArch64RegisterBankInfo &RBI, 166 const MachineRegisterInfo &MRI, 167 const AArch64RegisterInfo &TRI) { 168 LLT Ty = MRI.getType(I.getOperand(0).getReg()); 169 if (!Ty.isValid()) { 170 DEBUG(dbgs() << "Generic binop register should be typed\n"); 171 return true; 172 } 173 174 const RegisterBank *PrevOpBank = nullptr; 175 for (auto &MO : I.operands()) { 176 // FIXME: Support non-register operands. 177 if (!MO.isReg()) { 178 DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n"); 179 return true; 180 } 181 182 // FIXME: Can generic operations have physical registers operands? If 183 // so, this will need to be taught about that, and we'll need to get the 184 // bank out of the minimal class for the register. 185 // Either way, this needs to be documented (and possibly verified). 186 if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) { 187 DEBUG(dbgs() << "Generic inst has physical register operand\n"); 188 return true; 189 } 190 191 const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI); 192 if (!OpBank) { 193 DEBUG(dbgs() << "Generic register has no bank or class\n"); 194 return true; 195 } 196 197 if (PrevOpBank && OpBank != PrevOpBank) { 198 DEBUG(dbgs() << "Generic inst operands have different banks\n"); 199 return true; 200 } 201 PrevOpBank = OpBank; 202 } 203 return false; 204 } 205 206 /// Select the AArch64 opcode for the basic binary operation \p GenericOpc 207 /// (such as G_OR or G_SDIV), appropriate for the register bank \p RegBankID 208 /// and of size \p OpSize. 209 /// \returns \p GenericOpc if the combination is unsupported. 210 static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, 211 unsigned OpSize) { 212 switch (RegBankID) { 213 case AArch64::GPRRegBankID: 214 if (OpSize == 32) { 215 switch (GenericOpc) { 216 case TargetOpcode::G_SHL: 217 return AArch64::LSLVWr; 218 case TargetOpcode::G_LSHR: 219 return AArch64::LSRVWr; 220 case TargetOpcode::G_ASHR: 221 return AArch64::ASRVWr; 222 default: 223 return GenericOpc; 224 } 225 } else if (OpSize == 64) { 226 switch (GenericOpc) { 227 case TargetOpcode::G_GEP: 228 return AArch64::ADDXrr; 229 case TargetOpcode::G_SHL: 230 return AArch64::LSLVXr; 231 case TargetOpcode::G_LSHR: 232 return AArch64::LSRVXr; 233 case TargetOpcode::G_ASHR: 234 return AArch64::ASRVXr; 235 default: 236 return GenericOpc; 237 } 238 } 239 break; 240 case AArch64::FPRRegBankID: 241 switch (OpSize) { 242 case 32: 243 switch (GenericOpc) { 244 case TargetOpcode::G_FADD: 245 return AArch64::FADDSrr; 246 case TargetOpcode::G_FSUB: 247 return AArch64::FSUBSrr; 248 case TargetOpcode::G_FMUL: 249 return AArch64::FMULSrr; 250 case TargetOpcode::G_FDIV: 251 return AArch64::FDIVSrr; 252 default: 253 return GenericOpc; 254 } 255 case 64: 256 switch (GenericOpc) { 257 case TargetOpcode::G_FADD: 258 return AArch64::FADDDrr; 259 case TargetOpcode::G_FSUB: 260 return AArch64::FSUBDrr; 261 case TargetOpcode::G_FMUL: 262 return AArch64::FMULDrr; 263 case TargetOpcode::G_FDIV: 264 return AArch64::FDIVDrr; 265 case TargetOpcode::G_OR: 266 return AArch64::ORRv8i8; 267 default: 268 return GenericOpc; 269 } 270 } 271 break; 272 } 273 return GenericOpc; 274 } 275 276 /// Select the AArch64 opcode for the G_LOAD or G_STORE operation \p GenericOpc, 277 /// appropriate for the (value) register bank \p RegBankID and of memory access 278 /// size \p OpSize. This returns the variant with the base+unsigned-immediate 279 /// addressing mode (e.g., LDRXui). 280 /// \returns \p GenericOpc if the combination is unsupported. 281 static unsigned selectLoadStoreUIOp(unsigned GenericOpc, unsigned RegBankID, 282 unsigned OpSize) { 283 const bool isStore = GenericOpc == TargetOpcode::G_STORE; 284 switch (RegBankID) { 285 case AArch64::GPRRegBankID: 286 switch (OpSize) { 287 case 8: 288 return isStore ? AArch64::STRBBui : AArch64::LDRBBui; 289 case 16: 290 return isStore ? AArch64::STRHHui : AArch64::LDRHHui; 291 case 32: 292 return isStore ? AArch64::STRWui : AArch64::LDRWui; 293 case 64: 294 return isStore ? AArch64::STRXui : AArch64::LDRXui; 295 } 296 break; 297 case AArch64::FPRRegBankID: 298 switch (OpSize) { 299 case 8: 300 return isStore ? AArch64::STRBui : AArch64::LDRBui; 301 case 16: 302 return isStore ? AArch64::STRHui : AArch64::LDRHui; 303 case 32: 304 return isStore ? AArch64::STRSui : AArch64::LDRSui; 305 case 64: 306 return isStore ? AArch64::STRDui : AArch64::LDRDui; 307 } 308 break; 309 } 310 return GenericOpc; 311 } 312 313 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, 314 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, 315 const RegisterBankInfo &RBI) { 316 317 unsigned DstReg = I.getOperand(0).getReg(); 318 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) { 319 assert(I.isCopy() && "Generic operators do not allow physical registers"); 320 return true; 321 } 322 323 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); 324 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); 325 unsigned SrcReg = I.getOperand(1).getReg(); 326 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI); 327 (void)SrcSize; 328 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) && 329 "No phys reg on generic operators"); 330 assert( 331 (DstSize == SrcSize || 332 // Copies are a mean to setup initial types, the number of 333 // bits may not exactly match. 334 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && 335 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI)) || 336 // Copies are a mean to copy bits around, as long as we are 337 // on the same register class, that's fine. Otherwise, that 338 // means we need some SUBREG_TO_REG or AND & co. 339 (((DstSize + 31) / 32 == (SrcSize + 31) / 32) && DstSize > SrcSize)) && 340 "Copy with different width?!"); 341 assert((DstSize <= 64 || RegBank.getID() == AArch64::FPRRegBankID) && 342 "GPRs cannot get more than 64-bit width values"); 343 const TargetRegisterClass *RC = nullptr; 344 345 if (RegBank.getID() == AArch64::FPRRegBankID) { 346 if (DstSize <= 16) 347 RC = &AArch64::FPR16RegClass; 348 else if (DstSize <= 32) 349 RC = &AArch64::FPR32RegClass; 350 else if (DstSize <= 64) 351 RC = &AArch64::FPR64RegClass; 352 else if (DstSize <= 128) 353 RC = &AArch64::FPR128RegClass; 354 else { 355 DEBUG(dbgs() << "Unexpected bitcast size " << DstSize << '\n'); 356 return false; 357 } 358 } else { 359 assert(RegBank.getID() == AArch64::GPRRegBankID && 360 "Bitcast for the flags?"); 361 RC = 362 DstSize <= 32 ? &AArch64::GPR32allRegClass : &AArch64::GPR64allRegClass; 363 } 364 365 // No need to constrain SrcReg. It will get constrained when 366 // we hit another of its use or its defs. 367 // Copies do not have constraints. 368 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { 369 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 370 << " operand\n"); 371 return false; 372 } 373 I.setDesc(TII.get(AArch64::COPY)); 374 return true; 375 } 376 377 static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) { 378 if (!DstTy.isScalar() || !SrcTy.isScalar()) 379 return GenericOpc; 380 381 const unsigned DstSize = DstTy.getSizeInBits(); 382 const unsigned SrcSize = SrcTy.getSizeInBits(); 383 384 switch (DstSize) { 385 case 32: 386 switch (SrcSize) { 387 case 32: 388 switch (GenericOpc) { 389 case TargetOpcode::G_SITOFP: 390 return AArch64::SCVTFUWSri; 391 case TargetOpcode::G_UITOFP: 392 return AArch64::UCVTFUWSri; 393 case TargetOpcode::G_FPTOSI: 394 return AArch64::FCVTZSUWSr; 395 case TargetOpcode::G_FPTOUI: 396 return AArch64::FCVTZUUWSr; 397 default: 398 return GenericOpc; 399 } 400 case 64: 401 switch (GenericOpc) { 402 case TargetOpcode::G_SITOFP: 403 return AArch64::SCVTFUXSri; 404 case TargetOpcode::G_UITOFP: 405 return AArch64::UCVTFUXSri; 406 case TargetOpcode::G_FPTOSI: 407 return AArch64::FCVTZSUWDr; 408 case TargetOpcode::G_FPTOUI: 409 return AArch64::FCVTZUUWDr; 410 default: 411 return GenericOpc; 412 } 413 default: 414 return GenericOpc; 415 } 416 case 64: 417 switch (SrcSize) { 418 case 32: 419 switch (GenericOpc) { 420 case TargetOpcode::G_SITOFP: 421 return AArch64::SCVTFUWDri; 422 case TargetOpcode::G_UITOFP: 423 return AArch64::UCVTFUWDri; 424 case TargetOpcode::G_FPTOSI: 425 return AArch64::FCVTZSUXSr; 426 case TargetOpcode::G_FPTOUI: 427 return AArch64::FCVTZUUXSr; 428 default: 429 return GenericOpc; 430 } 431 case 64: 432 switch (GenericOpc) { 433 case TargetOpcode::G_SITOFP: 434 return AArch64::SCVTFUXDri; 435 case TargetOpcode::G_UITOFP: 436 return AArch64::UCVTFUXDri; 437 case TargetOpcode::G_FPTOSI: 438 return AArch64::FCVTZSUXDr; 439 case TargetOpcode::G_FPTOUI: 440 return AArch64::FCVTZUUXDr; 441 default: 442 return GenericOpc; 443 } 444 default: 445 return GenericOpc; 446 } 447 default: 448 return GenericOpc; 449 }; 450 return GenericOpc; 451 } 452 453 static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) { 454 switch (P) { 455 default: 456 llvm_unreachable("Unknown condition code!"); 457 case CmpInst::ICMP_NE: 458 return AArch64CC::NE; 459 case CmpInst::ICMP_EQ: 460 return AArch64CC::EQ; 461 case CmpInst::ICMP_SGT: 462 return AArch64CC::GT; 463 case CmpInst::ICMP_SGE: 464 return AArch64CC::GE; 465 case CmpInst::ICMP_SLT: 466 return AArch64CC::LT; 467 case CmpInst::ICMP_SLE: 468 return AArch64CC::LE; 469 case CmpInst::ICMP_UGT: 470 return AArch64CC::HI; 471 case CmpInst::ICMP_UGE: 472 return AArch64CC::HS; 473 case CmpInst::ICMP_ULT: 474 return AArch64CC::LO; 475 case CmpInst::ICMP_ULE: 476 return AArch64CC::LS; 477 } 478 } 479 480 static void changeFCMPPredToAArch64CC(CmpInst::Predicate P, 481 AArch64CC::CondCode &CondCode, 482 AArch64CC::CondCode &CondCode2) { 483 CondCode2 = AArch64CC::AL; 484 switch (P) { 485 default: 486 llvm_unreachable("Unknown FP condition!"); 487 case CmpInst::FCMP_OEQ: 488 CondCode = AArch64CC::EQ; 489 break; 490 case CmpInst::FCMP_OGT: 491 CondCode = AArch64CC::GT; 492 break; 493 case CmpInst::FCMP_OGE: 494 CondCode = AArch64CC::GE; 495 break; 496 case CmpInst::FCMP_OLT: 497 CondCode = AArch64CC::MI; 498 break; 499 case CmpInst::FCMP_OLE: 500 CondCode = AArch64CC::LS; 501 break; 502 case CmpInst::FCMP_ONE: 503 CondCode = AArch64CC::MI; 504 CondCode2 = AArch64CC::GT; 505 break; 506 case CmpInst::FCMP_ORD: 507 CondCode = AArch64CC::VC; 508 break; 509 case CmpInst::FCMP_UNO: 510 CondCode = AArch64CC::VS; 511 break; 512 case CmpInst::FCMP_UEQ: 513 CondCode = AArch64CC::EQ; 514 CondCode2 = AArch64CC::VS; 515 break; 516 case CmpInst::FCMP_UGT: 517 CondCode = AArch64CC::HI; 518 break; 519 case CmpInst::FCMP_UGE: 520 CondCode = AArch64CC::PL; 521 break; 522 case CmpInst::FCMP_ULT: 523 CondCode = AArch64CC::LT; 524 break; 525 case CmpInst::FCMP_ULE: 526 CondCode = AArch64CC::LE; 527 break; 528 case CmpInst::FCMP_UNE: 529 CondCode = AArch64CC::NE; 530 break; 531 } 532 } 533 534 bool AArch64InstructionSelector::selectCompareBranch( 535 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { 536 537 const unsigned CondReg = I.getOperand(0).getReg(); 538 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB(); 539 MachineInstr *CCMI = MRI.getVRegDef(CondReg); 540 if (CCMI->getOpcode() == TargetOpcode::G_TRUNC) 541 CCMI = MRI.getVRegDef(CCMI->getOperand(1).getReg()); 542 if (CCMI->getOpcode() != TargetOpcode::G_ICMP) 543 return false; 544 545 unsigned LHS = CCMI->getOperand(2).getReg(); 546 unsigned RHS = CCMI->getOperand(3).getReg(); 547 if (!getConstantVRegVal(RHS, MRI)) 548 std::swap(RHS, LHS); 549 550 const auto RHSImm = getConstantVRegVal(RHS, MRI); 551 if (!RHSImm || *RHSImm != 0) 552 return false; 553 554 const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI); 555 if (RB.getID() != AArch64::GPRRegBankID) 556 return false; 557 558 const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate(); 559 if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ) 560 return false; 561 562 const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits(); 563 unsigned CBOpc = 0; 564 if (CmpWidth <= 32) 565 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW); 566 else if (CmpWidth == 64) 567 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX); 568 else 569 return false; 570 571 auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc)) 572 .addUse(LHS) 573 .addMBB(DestMBB); 574 575 constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI); 576 I.eraseFromParent(); 577 return true; 578 } 579 580 bool AArch64InstructionSelector::selectVaStartAAPCS( 581 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { 582 return false; 583 } 584 585 bool AArch64InstructionSelector::selectVaStartDarwin( 586 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { 587 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>(); 588 unsigned ListReg = I.getOperand(0).getReg(); 589 590 unsigned ArgsAddrReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass); 591 592 auto MIB = 593 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::ADDXri)) 594 .addDef(ArgsAddrReg) 595 .addFrameIndex(FuncInfo->getVarArgsStackIndex()) 596 .addImm(0) 597 .addImm(0); 598 599 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); 600 601 MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::STRXui)) 602 .addUse(ArgsAddrReg) 603 .addUse(ListReg) 604 .addImm(0) 605 .addMemOperand(*I.memoperands_begin()); 606 607 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); 608 I.eraseFromParent(); 609 return true; 610 } 611 612 bool AArch64InstructionSelector::select(MachineInstr &I, 613 CodeGenCoverage &CoverageInfo) const { 614 assert(I.getParent() && "Instruction should be in a basic block!"); 615 assert(I.getParent()->getParent() && "Instruction should be in a function!"); 616 617 MachineBasicBlock &MBB = *I.getParent(); 618 MachineFunction &MF = *MBB.getParent(); 619 MachineRegisterInfo &MRI = MF.getRegInfo(); 620 621 unsigned Opcode = I.getOpcode(); 622 // G_PHI requires same handling as PHI 623 if (!isPreISelGenericOpcode(Opcode) || Opcode == TargetOpcode::G_PHI) { 624 // Certain non-generic instructions also need some special handling. 625 626 if (Opcode == TargetOpcode::LOAD_STACK_GUARD) 627 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 628 629 if (Opcode == TargetOpcode::PHI || Opcode == TargetOpcode::G_PHI) { 630 const unsigned DefReg = I.getOperand(0).getReg(); 631 const LLT DefTy = MRI.getType(DefReg); 632 633 const TargetRegisterClass *DefRC = nullptr; 634 if (TargetRegisterInfo::isPhysicalRegister(DefReg)) { 635 DefRC = TRI.getRegClass(DefReg); 636 } else { 637 const RegClassOrRegBank &RegClassOrBank = 638 MRI.getRegClassOrRegBank(DefReg); 639 640 DefRC = RegClassOrBank.dyn_cast<const TargetRegisterClass *>(); 641 if (!DefRC) { 642 if (!DefTy.isValid()) { 643 DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n"); 644 return false; 645 } 646 const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>(); 647 DefRC = getRegClassForTypeOnBank(DefTy, RB, RBI); 648 if (!DefRC) { 649 DEBUG(dbgs() << "PHI operand has unexpected size/bank\n"); 650 return false; 651 } 652 } 653 } 654 I.setDesc(TII.get(TargetOpcode::PHI)); 655 656 return RBI.constrainGenericRegister(DefReg, *DefRC, MRI); 657 } 658 659 if (I.isCopy()) 660 return selectCopy(I, TII, MRI, TRI, RBI); 661 662 return true; 663 } 664 665 666 if (I.getNumOperands() != I.getNumExplicitOperands()) { 667 DEBUG(dbgs() << "Generic instruction has unexpected implicit operands\n"); 668 return false; 669 } 670 671 if (selectImpl(I, CoverageInfo)) 672 return true; 673 674 LLT Ty = 675 I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{}; 676 677 switch (Opcode) { 678 case TargetOpcode::G_BRCOND: { 679 if (Ty.getSizeInBits() > 32) { 680 // We shouldn't need this on AArch64, but it would be implemented as an 681 // EXTRACT_SUBREG followed by a TBNZW because TBNZX has no encoding if the 682 // bit being tested is < 32. 683 DEBUG(dbgs() << "G_BRCOND has type: " << Ty 684 << ", expected at most 32-bits"); 685 return false; 686 } 687 688 const unsigned CondReg = I.getOperand(0).getReg(); 689 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB(); 690 691 if (selectCompareBranch(I, MF, MRI)) 692 return true; 693 694 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW)) 695 .addUse(CondReg) 696 .addImm(/*bit offset=*/0) 697 .addMBB(DestMBB); 698 699 I.eraseFromParent(); 700 return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI); 701 } 702 703 case TargetOpcode::G_BRINDIRECT: { 704 I.setDesc(TII.get(AArch64::BR)); 705 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 706 } 707 708 case TargetOpcode::G_FCONSTANT: 709 case TargetOpcode::G_CONSTANT: { 710 const bool isFP = Opcode == TargetOpcode::G_FCONSTANT; 711 712 const LLT s32 = LLT::scalar(32); 713 const LLT s64 = LLT::scalar(64); 714 const LLT p0 = LLT::pointer(0, 64); 715 716 const unsigned DefReg = I.getOperand(0).getReg(); 717 const LLT DefTy = MRI.getType(DefReg); 718 const unsigned DefSize = DefTy.getSizeInBits(); 719 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); 720 721 // FIXME: Redundant check, but even less readable when factored out. 722 if (isFP) { 723 if (Ty != s32 && Ty != s64) { 724 DEBUG(dbgs() << "Unable to materialize FP " << Ty 725 << " constant, expected: " << s32 << " or " << s64 726 << '\n'); 727 return false; 728 } 729 730 if (RB.getID() != AArch64::FPRRegBankID) { 731 DEBUG(dbgs() << "Unable to materialize FP " << Ty 732 << " constant on bank: " << RB << ", expected: FPR\n"); 733 return false; 734 } 735 736 // The case when we have 0.0 is covered by tablegen. Reject it here so we 737 // can be sure tablegen works correctly and isn't rescued by this code. 738 if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0)) 739 return false; 740 } else { 741 // s32 and s64 are covered by tablegen. 742 if (Ty != p0) { 743 DEBUG(dbgs() << "Unable to materialize integer " << Ty 744 << " constant, expected: " << s32 << ", " << s64 << ", or " 745 << p0 << '\n'); 746 return false; 747 } 748 749 if (RB.getID() != AArch64::GPRRegBankID) { 750 DEBUG(dbgs() << "Unable to materialize integer " << Ty 751 << " constant on bank: " << RB << ", expected: GPR\n"); 752 return false; 753 } 754 } 755 756 const unsigned MovOpc = 757 DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm; 758 759 I.setDesc(TII.get(MovOpc)); 760 761 if (isFP) { 762 const TargetRegisterClass &GPRRC = 763 DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass; 764 const TargetRegisterClass &FPRRC = 765 DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass; 766 767 const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC); 768 MachineOperand &RegOp = I.getOperand(0); 769 RegOp.setReg(DefGPRReg); 770 771 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(), 772 TII.get(AArch64::COPY)) 773 .addDef(DefReg) 774 .addUse(DefGPRReg); 775 776 if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) { 777 DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n"); 778 return false; 779 } 780 781 MachineOperand &ImmOp = I.getOperand(1); 782 // FIXME: Is going through int64_t always correct? 783 ImmOp.ChangeToImmediate( 784 ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue()); 785 } else if (I.getOperand(1).isCImm()) { 786 uint64_t Val = I.getOperand(1).getCImm()->getZExtValue(); 787 I.getOperand(1).ChangeToImmediate(Val); 788 } else if (I.getOperand(1).isImm()) { 789 uint64_t Val = I.getOperand(1).getImm(); 790 I.getOperand(1).ChangeToImmediate(Val); 791 } 792 793 constrainSelectedInstRegOperands(I, TII, TRI, RBI); 794 return true; 795 } 796 case TargetOpcode::G_EXTRACT: { 797 LLT SrcTy = MRI.getType(I.getOperand(1).getReg()); 798 // Larger extracts are vectors, same-size extracts should be something else 799 // by now (either split up or simplified to a COPY). 800 if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32) 801 return false; 802 803 I.setDesc(TII.get(AArch64::UBFMXri)); 804 MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() + 805 Ty.getSizeInBits() - 1); 806 807 unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64)); 808 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(), 809 TII.get(AArch64::COPY)) 810 .addDef(I.getOperand(0).getReg()) 811 .addUse(DstReg, 0, AArch64::sub_32); 812 RBI.constrainGenericRegister(I.getOperand(0).getReg(), 813 AArch64::GPR32RegClass, MRI); 814 I.getOperand(0).setReg(DstReg); 815 816 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 817 } 818 819 case TargetOpcode::G_INSERT: { 820 LLT SrcTy = MRI.getType(I.getOperand(2).getReg()); 821 // Larger inserts are vectors, same-size ones should be something else by 822 // now (split up or turned into COPYs). 823 if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32) 824 return false; 825 826 I.setDesc(TII.get(AArch64::BFMXri)); 827 unsigned LSB = I.getOperand(3).getImm(); 828 unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits(); 829 I.getOperand(3).setImm((64 - LSB) % 64); 830 MachineInstrBuilder(MF, I).addImm(Width - 1); 831 832 unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64)); 833 BuildMI(MBB, I.getIterator(), I.getDebugLoc(), 834 TII.get(AArch64::SUBREG_TO_REG)) 835 .addDef(SrcReg) 836 .addImm(0) 837 .addUse(I.getOperand(2).getReg()) 838 .addImm(AArch64::sub_32); 839 RBI.constrainGenericRegister(I.getOperand(2).getReg(), 840 AArch64::GPR32RegClass, MRI); 841 I.getOperand(2).setReg(SrcReg); 842 843 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 844 } 845 case TargetOpcode::G_FRAME_INDEX: { 846 // allocas and G_FRAME_INDEX are only supported in addrspace(0). 847 if (Ty != LLT::pointer(0, 64)) { 848 DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty 849 << ", expected: " << LLT::pointer(0, 64) << '\n'); 850 return false; 851 } 852 I.setDesc(TII.get(AArch64::ADDXri)); 853 854 // MOs for a #0 shifted immediate. 855 I.addOperand(MachineOperand::CreateImm(0)); 856 I.addOperand(MachineOperand::CreateImm(0)); 857 858 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 859 } 860 861 case TargetOpcode::G_GLOBAL_VALUE: { 862 auto GV = I.getOperand(1).getGlobal(); 863 if (GV->isThreadLocal()) { 864 // FIXME: we don't support TLS yet. 865 return false; 866 } 867 unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM); 868 if (OpFlags & AArch64II::MO_GOT) { 869 I.setDesc(TII.get(AArch64::LOADgot)); 870 I.getOperand(1).setTargetFlags(OpFlags); 871 } else { 872 I.setDesc(TII.get(AArch64::MOVaddr)); 873 I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE); 874 MachineInstrBuilder MIB(MF, I); 875 MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(), 876 OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC); 877 } 878 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 879 } 880 881 case TargetOpcode::G_LOAD: 882 case TargetOpcode::G_STORE: { 883 LLT MemTy = Ty; 884 LLT PtrTy = MRI.getType(I.getOperand(1).getReg()); 885 886 if (PtrTy != LLT::pointer(0, 64)) { 887 DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy 888 << ", expected: " << LLT::pointer(0, 64) << '\n'); 889 return false; 890 } 891 892 auto &MemOp = **I.memoperands_begin(); 893 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { 894 DEBUG(dbgs() << "Atomic load/store not supported yet\n"); 895 return false; 896 } 897 898 const unsigned PtrReg = I.getOperand(1).getReg(); 899 #ifndef NDEBUG 900 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI); 901 // Sanity-check the pointer register. 902 assert(PtrRB.getID() == AArch64::GPRRegBankID && 903 "Load/Store pointer operand isn't a GPR"); 904 assert(MRI.getType(PtrReg).isPointer() && 905 "Load/Store pointer operand isn't a pointer"); 906 #endif 907 908 const unsigned ValReg = I.getOperand(0).getReg(); 909 const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI); 910 911 const unsigned NewOpc = 912 selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemTy.getSizeInBits()); 913 if (NewOpc == I.getOpcode()) 914 return false; 915 916 I.setDesc(TII.get(NewOpc)); 917 918 uint64_t Offset = 0; 919 auto *PtrMI = MRI.getVRegDef(PtrReg); 920 921 // Try to fold a GEP into our unsigned immediate addressing mode. 922 if (PtrMI->getOpcode() == TargetOpcode::G_GEP) { 923 if (auto COff = getConstantVRegVal(PtrMI->getOperand(2).getReg(), MRI)) { 924 int64_t Imm = *COff; 925 const unsigned Size = MemTy.getSizeInBits() / 8; 926 const unsigned Scale = Log2_32(Size); 927 if ((Imm & (Size - 1)) == 0 && Imm >= 0 && Imm < (0x1000 << Scale)) { 928 unsigned Ptr2Reg = PtrMI->getOperand(1).getReg(); 929 I.getOperand(1).setReg(Ptr2Reg); 930 PtrMI = MRI.getVRegDef(Ptr2Reg); 931 Offset = Imm / Size; 932 } 933 } 934 } 935 936 // If we haven't folded anything into our addressing mode yet, try to fold 937 // a frame index into the base+offset. 938 if (!Offset && PtrMI->getOpcode() == TargetOpcode::G_FRAME_INDEX) 939 I.getOperand(1).ChangeToFrameIndex(PtrMI->getOperand(1).getIndex()); 940 941 I.addOperand(MachineOperand::CreateImm(Offset)); 942 943 // If we're storing a 0, use WZR/XZR. 944 if (auto CVal = getConstantVRegVal(ValReg, MRI)) { 945 if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) { 946 if (I.getOpcode() == AArch64::STRWui) 947 I.getOperand(0).setReg(AArch64::WZR); 948 else if (I.getOpcode() == AArch64::STRXui) 949 I.getOperand(0).setReg(AArch64::XZR); 950 } 951 } 952 953 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 954 } 955 956 case TargetOpcode::G_SMULH: 957 case TargetOpcode::G_UMULH: { 958 // Reject the various things we don't support yet. 959 if (unsupportedBinOp(I, RBI, MRI, TRI)) 960 return false; 961 962 const unsigned DefReg = I.getOperand(0).getReg(); 963 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); 964 965 if (RB.getID() != AArch64::GPRRegBankID) { 966 DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n"); 967 return false; 968 } 969 970 if (Ty != LLT::scalar(64)) { 971 DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty 972 << ", expected: " << LLT::scalar(64) << '\n'); 973 return false; 974 } 975 976 unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr 977 : AArch64::UMULHrr; 978 I.setDesc(TII.get(NewOpc)); 979 980 // Now that we selected an opcode, we need to constrain the register 981 // operands to use appropriate classes. 982 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 983 } 984 case TargetOpcode::G_FADD: 985 case TargetOpcode::G_FSUB: 986 case TargetOpcode::G_FMUL: 987 case TargetOpcode::G_FDIV: 988 989 case TargetOpcode::G_OR: 990 case TargetOpcode::G_SHL: 991 case TargetOpcode::G_LSHR: 992 case TargetOpcode::G_ASHR: 993 case TargetOpcode::G_GEP: { 994 // Reject the various things we don't support yet. 995 if (unsupportedBinOp(I, RBI, MRI, TRI)) 996 return false; 997 998 const unsigned OpSize = Ty.getSizeInBits(); 999 1000 const unsigned DefReg = I.getOperand(0).getReg(); 1001 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); 1002 1003 const unsigned NewOpc = selectBinaryOp(I.getOpcode(), RB.getID(), OpSize); 1004 if (NewOpc == I.getOpcode()) 1005 return false; 1006 1007 I.setDesc(TII.get(NewOpc)); 1008 // FIXME: Should the type be always reset in setDesc? 1009 1010 // Now that we selected an opcode, we need to constrain the register 1011 // operands to use appropriate classes. 1012 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1013 } 1014 1015 case TargetOpcode::G_PTR_MASK: { 1016 uint64_t Align = I.getOperand(2).getImm(); 1017 if (Align >= 64 || Align == 0) 1018 return false; 1019 1020 uint64_t Mask = ~((1ULL << Align) - 1); 1021 I.setDesc(TII.get(AArch64::ANDXri)); 1022 I.getOperand(2).setImm(AArch64_AM::encodeLogicalImmediate(Mask, 64)); 1023 1024 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1025 } 1026 case TargetOpcode::G_PTRTOINT: 1027 case TargetOpcode::G_TRUNC: { 1028 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()); 1029 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg()); 1030 1031 const unsigned DstReg = I.getOperand(0).getReg(); 1032 const unsigned SrcReg = I.getOperand(1).getReg(); 1033 1034 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI); 1035 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI); 1036 1037 if (DstRB.getID() != SrcRB.getID()) { 1038 DEBUG(dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n"); 1039 return false; 1040 } 1041 1042 if (DstRB.getID() == AArch64::GPRRegBankID) { 1043 const TargetRegisterClass *DstRC = 1044 getRegClassForTypeOnBank(DstTy, DstRB, RBI); 1045 if (!DstRC) 1046 return false; 1047 1048 const TargetRegisterClass *SrcRC = 1049 getRegClassForTypeOnBank(SrcTy, SrcRB, RBI); 1050 if (!SrcRC) 1051 return false; 1052 1053 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || 1054 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { 1055 DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n"); 1056 return false; 1057 } 1058 1059 if (DstRC == SrcRC) { 1060 // Nothing to be done 1061 } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) && 1062 SrcTy == LLT::scalar(64)) { 1063 llvm_unreachable("TableGen can import this case"); 1064 return false; 1065 } else if (DstRC == &AArch64::GPR32RegClass && 1066 SrcRC == &AArch64::GPR64RegClass) { 1067 I.getOperand(1).setSubReg(AArch64::sub_32); 1068 } else { 1069 DEBUG(dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n"); 1070 return false; 1071 } 1072 1073 I.setDesc(TII.get(TargetOpcode::COPY)); 1074 return true; 1075 } else if (DstRB.getID() == AArch64::FPRRegBankID) { 1076 if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) { 1077 I.setDesc(TII.get(AArch64::XTNv4i16)); 1078 constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1079 return true; 1080 } 1081 } 1082 1083 return false; 1084 } 1085 1086 case TargetOpcode::G_ANYEXT: { 1087 const unsigned DstReg = I.getOperand(0).getReg(); 1088 const unsigned SrcReg = I.getOperand(1).getReg(); 1089 1090 const RegisterBank &RBDst = *RBI.getRegBank(DstReg, MRI, TRI); 1091 if (RBDst.getID() != AArch64::GPRRegBankID) { 1092 DEBUG(dbgs() << "G_ANYEXT on bank: " << RBDst << ", expected: GPR\n"); 1093 return false; 1094 } 1095 1096 const RegisterBank &RBSrc = *RBI.getRegBank(SrcReg, MRI, TRI); 1097 if (RBSrc.getID() != AArch64::GPRRegBankID) { 1098 DEBUG(dbgs() << "G_ANYEXT on bank: " << RBSrc << ", expected: GPR\n"); 1099 return false; 1100 } 1101 1102 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); 1103 1104 if (DstSize == 0) { 1105 DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n"); 1106 return false; 1107 } 1108 1109 if (DstSize != 64 && DstSize > 32) { 1110 DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize 1111 << ", expected: 32 or 64\n"); 1112 return false; 1113 } 1114 // At this point G_ANYEXT is just like a plain COPY, but we need 1115 // to explicitly form the 64-bit value if any. 1116 if (DstSize > 32) { 1117 unsigned ExtSrc = MRI.createVirtualRegister(&AArch64::GPR64allRegClass); 1118 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG)) 1119 .addDef(ExtSrc) 1120 .addImm(0) 1121 .addUse(SrcReg) 1122 .addImm(AArch64::sub_32); 1123 I.getOperand(1).setReg(ExtSrc); 1124 } 1125 return selectCopy(I, TII, MRI, TRI, RBI); 1126 } 1127 1128 case TargetOpcode::G_ZEXT: 1129 case TargetOpcode::G_SEXT: { 1130 unsigned Opcode = I.getOpcode(); 1131 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()), 1132 SrcTy = MRI.getType(I.getOperand(1).getReg()); 1133 const bool isSigned = Opcode == TargetOpcode::G_SEXT; 1134 const unsigned DefReg = I.getOperand(0).getReg(); 1135 const unsigned SrcReg = I.getOperand(1).getReg(); 1136 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); 1137 1138 if (RB.getID() != AArch64::GPRRegBankID) { 1139 DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB 1140 << ", expected: GPR\n"); 1141 return false; 1142 } 1143 1144 MachineInstr *ExtI; 1145 if (DstTy == LLT::scalar(64)) { 1146 // FIXME: Can we avoid manually doing this? 1147 if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) { 1148 DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode) 1149 << " operand\n"); 1150 return false; 1151 } 1152 1153 const unsigned SrcXReg = 1154 MRI.createVirtualRegister(&AArch64::GPR64RegClass); 1155 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG)) 1156 .addDef(SrcXReg) 1157 .addImm(0) 1158 .addUse(SrcReg) 1159 .addImm(AArch64::sub_32); 1160 1161 const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri; 1162 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc)) 1163 .addDef(DefReg) 1164 .addUse(SrcXReg) 1165 .addImm(0) 1166 .addImm(SrcTy.getSizeInBits() - 1); 1167 } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) { 1168 const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri; 1169 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc)) 1170 .addDef(DefReg) 1171 .addUse(SrcReg) 1172 .addImm(0) 1173 .addImm(SrcTy.getSizeInBits() - 1); 1174 } else { 1175 return false; 1176 } 1177 1178 constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI); 1179 1180 I.eraseFromParent(); 1181 return true; 1182 } 1183 1184 case TargetOpcode::G_SITOFP: 1185 case TargetOpcode::G_UITOFP: 1186 case TargetOpcode::G_FPTOSI: 1187 case TargetOpcode::G_FPTOUI: { 1188 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()), 1189 SrcTy = MRI.getType(I.getOperand(1).getReg()); 1190 const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy); 1191 if (NewOpc == Opcode) 1192 return false; 1193 1194 I.setDesc(TII.get(NewOpc)); 1195 constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1196 1197 return true; 1198 } 1199 1200 1201 case TargetOpcode::G_INTTOPTR: 1202 // The importer is currently unable to import pointer types since they 1203 // didn't exist in SelectionDAG. 1204 return selectCopy(I, TII, MRI, TRI, RBI); 1205 1206 case TargetOpcode::G_BITCAST: 1207 // Imported SelectionDAG rules can handle every bitcast except those that 1208 // bitcast from a type to the same type. Ideally, these shouldn't occur 1209 // but we might not run an optimizer that deletes them. 1210 if (MRI.getType(I.getOperand(0).getReg()) == 1211 MRI.getType(I.getOperand(1).getReg())) 1212 return selectCopy(I, TII, MRI, TRI, RBI); 1213 return false; 1214 1215 case TargetOpcode::G_SELECT: { 1216 if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) { 1217 DEBUG(dbgs() << "G_SELECT cond has type: " << Ty 1218 << ", expected: " << LLT::scalar(1) << '\n'); 1219 return false; 1220 } 1221 1222 const unsigned CondReg = I.getOperand(1).getReg(); 1223 const unsigned TReg = I.getOperand(2).getReg(); 1224 const unsigned FReg = I.getOperand(3).getReg(); 1225 1226 unsigned CSelOpc = 0; 1227 1228 if (Ty == LLT::scalar(32)) { 1229 CSelOpc = AArch64::CSELWr; 1230 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) { 1231 CSelOpc = AArch64::CSELXr; 1232 } else { 1233 return false; 1234 } 1235 1236 MachineInstr &TstMI = 1237 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri)) 1238 .addDef(AArch64::WZR) 1239 .addUse(CondReg) 1240 .addImm(AArch64_AM::encodeLogicalImmediate(1, 32)); 1241 1242 MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc)) 1243 .addDef(I.getOperand(0).getReg()) 1244 .addUse(TReg) 1245 .addUse(FReg) 1246 .addImm(AArch64CC::NE); 1247 1248 constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI); 1249 constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI); 1250 1251 I.eraseFromParent(); 1252 return true; 1253 } 1254 case TargetOpcode::G_ICMP: { 1255 if (Ty != LLT::scalar(32)) { 1256 DEBUG(dbgs() << "G_ICMP result has type: " << Ty 1257 << ", expected: " << LLT::scalar(32) << '\n'); 1258 return false; 1259 } 1260 1261 unsigned CmpOpc = 0; 1262 unsigned ZReg = 0; 1263 1264 LLT CmpTy = MRI.getType(I.getOperand(2).getReg()); 1265 if (CmpTy == LLT::scalar(32)) { 1266 CmpOpc = AArch64::SUBSWrr; 1267 ZReg = AArch64::WZR; 1268 } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) { 1269 CmpOpc = AArch64::SUBSXrr; 1270 ZReg = AArch64::XZR; 1271 } else { 1272 return false; 1273 } 1274 1275 // CSINC increments the result by one when the condition code is false. 1276 // Therefore, we have to invert the predicate to get an increment by 1 when 1277 // the predicate is true. 1278 const AArch64CC::CondCode invCC = 1279 changeICMPPredToAArch64CC(CmpInst::getInversePredicate( 1280 (CmpInst::Predicate)I.getOperand(1).getPredicate())); 1281 1282 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc)) 1283 .addDef(ZReg) 1284 .addUse(I.getOperand(2).getReg()) 1285 .addUse(I.getOperand(3).getReg()); 1286 1287 MachineInstr &CSetMI = 1288 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr)) 1289 .addDef(I.getOperand(0).getReg()) 1290 .addUse(AArch64::WZR) 1291 .addUse(AArch64::WZR) 1292 .addImm(invCC); 1293 1294 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI); 1295 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI); 1296 1297 I.eraseFromParent(); 1298 return true; 1299 } 1300 1301 case TargetOpcode::G_FCMP: { 1302 if (Ty != LLT::scalar(32)) { 1303 DEBUG(dbgs() << "G_FCMP result has type: " << Ty 1304 << ", expected: " << LLT::scalar(32) << '\n'); 1305 return false; 1306 } 1307 1308 unsigned CmpOpc = 0; 1309 LLT CmpTy = MRI.getType(I.getOperand(2).getReg()); 1310 if (CmpTy == LLT::scalar(32)) { 1311 CmpOpc = AArch64::FCMPSrr; 1312 } else if (CmpTy == LLT::scalar(64)) { 1313 CmpOpc = AArch64::FCMPDrr; 1314 } else { 1315 return false; 1316 } 1317 1318 // FIXME: regbank 1319 1320 AArch64CC::CondCode CC1, CC2; 1321 changeFCMPPredToAArch64CC( 1322 (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2); 1323 1324 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc)) 1325 .addUse(I.getOperand(2).getReg()) 1326 .addUse(I.getOperand(3).getReg()); 1327 1328 const unsigned DefReg = I.getOperand(0).getReg(); 1329 unsigned Def1Reg = DefReg; 1330 if (CC2 != AArch64CC::AL) 1331 Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass); 1332 1333 MachineInstr &CSetMI = 1334 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr)) 1335 .addDef(Def1Reg) 1336 .addUse(AArch64::WZR) 1337 .addUse(AArch64::WZR) 1338 .addImm(getInvertedCondCode(CC1)); 1339 1340 if (CC2 != AArch64CC::AL) { 1341 unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass); 1342 MachineInstr &CSet2MI = 1343 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr)) 1344 .addDef(Def2Reg) 1345 .addUse(AArch64::WZR) 1346 .addUse(AArch64::WZR) 1347 .addImm(getInvertedCondCode(CC2)); 1348 MachineInstr &OrMI = 1349 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr)) 1350 .addDef(DefReg) 1351 .addUse(Def1Reg) 1352 .addUse(Def2Reg); 1353 constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI); 1354 constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI); 1355 } 1356 1357 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI); 1358 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI); 1359 1360 I.eraseFromParent(); 1361 return true; 1362 } 1363 case TargetOpcode::G_VASTART: 1364 return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI) 1365 : selectVaStartAAPCS(I, MF, MRI); 1366 case TargetOpcode::G_IMPLICIT_DEF: 1367 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF)); 1368 return true; 1369 } 1370 1371 return false; 1372 } 1373 1374 /// SelectArithImmed - Select an immediate value that can be represented as 1375 /// a 12-bit value shifted left by either 0 or 12. If so, return true with 1376 /// Val set to the 12-bit value and Shift set to the shifter operand. 1377 InstructionSelector::ComplexRendererFns 1378 AArch64InstructionSelector::selectArithImmed(MachineOperand &Root) const { 1379 MachineInstr &MI = *Root.getParent(); 1380 MachineBasicBlock &MBB = *MI.getParent(); 1381 MachineFunction &MF = *MBB.getParent(); 1382 MachineRegisterInfo &MRI = MF.getRegInfo(); 1383 1384 // This function is called from the addsub_shifted_imm ComplexPattern, 1385 // which lists [imm] as the list of opcode it's interested in, however 1386 // we still need to check whether the operand is actually an immediate 1387 // here because the ComplexPattern opcode list is only used in 1388 // root-level opcode matching. 1389 uint64_t Immed; 1390 if (Root.isImm()) 1391 Immed = Root.getImm(); 1392 else if (Root.isCImm()) 1393 Immed = Root.getCImm()->getZExtValue(); 1394 else if (Root.isReg()) { 1395 MachineInstr *Def = MRI.getVRegDef(Root.getReg()); 1396 if (Def->getOpcode() != TargetOpcode::G_CONSTANT) 1397 return None; 1398 MachineOperand &Op1 = Def->getOperand(1); 1399 if (!Op1.isCImm() || Op1.getCImm()->getBitWidth() > 64) 1400 return None; 1401 Immed = Op1.getCImm()->getZExtValue(); 1402 } else 1403 return None; 1404 1405 unsigned ShiftAmt; 1406 1407 if (Immed >> 12 == 0) { 1408 ShiftAmt = 0; 1409 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) { 1410 ShiftAmt = 12; 1411 Immed = Immed >> 12; 1412 } else 1413 return None; 1414 1415 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt); 1416 return {{ 1417 [=](MachineInstrBuilder &MIB) { MIB.addImm(Immed); }, 1418 [=](MachineInstrBuilder &MIB) { MIB.addImm(ShVal); }, 1419 }}; 1420 } 1421 1422 /// Select a "register plus unscaled signed 9-bit immediate" address. This 1423 /// should only match when there is an offset that is not valid for a scaled 1424 /// immediate addressing mode. The "Size" argument is the size in bytes of the 1425 /// memory reference, which is needed here to know what is valid for a scaled 1426 /// immediate. 1427 InstructionSelector::ComplexRendererFns 1428 AArch64InstructionSelector::selectAddrModeUnscaled(MachineOperand &Root, 1429 unsigned Size) const { 1430 MachineRegisterInfo &MRI = 1431 Root.getParent()->getParent()->getParent()->getRegInfo(); 1432 1433 if (!Root.isReg()) 1434 return None; 1435 1436 if (!isBaseWithConstantOffset(Root, MRI)) 1437 return None; 1438 1439 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg()); 1440 if (!RootDef) 1441 return None; 1442 1443 MachineOperand &OffImm = RootDef->getOperand(2); 1444 if (!OffImm.isReg()) 1445 return None; 1446 MachineInstr *RHS = MRI.getVRegDef(OffImm.getReg()); 1447 if (!RHS || RHS->getOpcode() != TargetOpcode::G_CONSTANT) 1448 return None; 1449 int64_t RHSC; 1450 MachineOperand &RHSOp1 = RHS->getOperand(1); 1451 if (!RHSOp1.isCImm() || RHSOp1.getCImm()->getBitWidth() > 64) 1452 return None; 1453 RHSC = RHSOp1.getCImm()->getSExtValue(); 1454 1455 // If the offset is valid as a scaled immediate, don't match here. 1456 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Log2_32(Size))) 1457 return None; 1458 if (RHSC >= -256 && RHSC < 256) { 1459 MachineOperand &Base = RootDef->getOperand(1); 1460 return {{ 1461 [=](MachineInstrBuilder &MIB) { MIB.add(Base); }, 1462 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }, 1463 }}; 1464 } 1465 return None; 1466 } 1467 1468 /// Select a "register plus scaled unsigned 12-bit immediate" address. The 1469 /// "Size" argument is the size in bytes of the memory reference, which 1470 /// determines the scale. 1471 InstructionSelector::ComplexRendererFns 1472 AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root, 1473 unsigned Size) const { 1474 MachineRegisterInfo &MRI = 1475 Root.getParent()->getParent()->getParent()->getRegInfo(); 1476 1477 if (!Root.isReg()) 1478 return None; 1479 1480 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg()); 1481 if (!RootDef) 1482 return None; 1483 1484 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) { 1485 return {{ 1486 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); }, 1487 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, 1488 }}; 1489 } 1490 1491 if (isBaseWithConstantOffset(Root, MRI)) { 1492 MachineOperand &LHS = RootDef->getOperand(1); 1493 MachineOperand &RHS = RootDef->getOperand(2); 1494 MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg()); 1495 MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg()); 1496 if (LHSDef && RHSDef) { 1497 int64_t RHSC = (int64_t)RHSDef->getOperand(1).getCImm()->getZExtValue(); 1498 unsigned Scale = Log2_32(Size); 1499 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) { 1500 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) 1501 return {{ 1502 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); }, 1503 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); }, 1504 }}; 1505 1506 return {{ 1507 [=](MachineInstrBuilder &MIB) { MIB.add(LHS); }, 1508 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); }, 1509 }}; 1510 } 1511 } 1512 } 1513 1514 // Before falling back to our general case, check if the unscaled 1515 // instructions can handle this. If so, that's preferable. 1516 if (selectAddrModeUnscaled(Root, Size).hasValue()) 1517 return None; 1518 1519 return {{ 1520 [=](MachineInstrBuilder &MIB) { MIB.add(Root); }, 1521 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, 1522 }}; 1523 } 1524 1525 namespace llvm { 1526 InstructionSelector * 1527 createAArch64InstructionSelector(const AArch64TargetMachine &TM, 1528 AArch64Subtarget &Subtarget, 1529 AArch64RegisterBankInfo &RBI) { 1530 return new AArch64InstructionSelector(TM, Subtarget, RBI); 1531 } 1532 } 1533