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