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