1 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines an instruction selector for the ARM target. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ARM.h" 14 #include "ARMBaseInstrInfo.h" 15 #include "ARMTargetMachine.h" 16 #include "MCTargetDesc/ARMAddressingModes.h" 17 #include "Utils/ARMBaseInfo.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/CodeGen/MachineFrameInfo.h" 20 #include "llvm/CodeGen/MachineFunction.h" 21 #include "llvm/CodeGen/MachineInstrBuilder.h" 22 #include "llvm/CodeGen/MachineRegisterInfo.h" 23 #include "llvm/CodeGen/SelectionDAG.h" 24 #include "llvm/CodeGen/SelectionDAGISel.h" 25 #include "llvm/CodeGen/TargetLowering.h" 26 #include "llvm/IR/CallingConv.h" 27 #include "llvm/IR/Constants.h" 28 #include "llvm/IR/DerivedTypes.h" 29 #include "llvm/IR/Function.h" 30 #include "llvm/IR/Intrinsics.h" 31 #include "llvm/IR/LLVMContext.h" 32 #include "llvm/Support/CommandLine.h" 33 #include "llvm/Support/Debug.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Target/TargetOptions.h" 36 37 using namespace llvm; 38 39 #define DEBUG_TYPE "arm-isel" 40 41 static cl::opt<bool> 42 DisableShifterOp("disable-shifter-op", cl::Hidden, 43 cl::desc("Disable isel of shifter-op"), 44 cl::init(false)); 45 46 //===--------------------------------------------------------------------===// 47 /// ARMDAGToDAGISel - ARM specific code to select ARM machine 48 /// instructions for SelectionDAG operations. 49 /// 50 namespace { 51 52 class ARMDAGToDAGISel : public SelectionDAGISel { 53 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 54 /// make the right decision when generating code for different targets. 55 const ARMSubtarget *Subtarget; 56 57 public: 58 explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm, CodeGenOpt::Level OptLevel) 59 : SelectionDAGISel(tm, OptLevel) {} 60 61 bool runOnMachineFunction(MachineFunction &MF) override { 62 // Reset the subtarget each time through. 63 Subtarget = &MF.getSubtarget<ARMSubtarget>(); 64 SelectionDAGISel::runOnMachineFunction(MF); 65 return true; 66 } 67 68 StringRef getPassName() const override { return "ARM Instruction Selection"; } 69 70 void PreprocessISelDAG() override; 71 72 /// getI32Imm - Return a target constant of type i32 with the specified 73 /// value. 74 inline SDValue getI32Imm(unsigned Imm, const SDLoc &dl) { 75 return CurDAG->getTargetConstant(Imm, dl, MVT::i32); 76 } 77 78 void Select(SDNode *N) override; 79 80 bool hasNoVMLxHazardUse(SDNode *N) const; 81 bool isShifterOpProfitable(const SDValue &Shift, 82 ARM_AM::ShiftOpc ShOpcVal, unsigned ShAmt); 83 bool SelectRegShifterOperand(SDValue N, SDValue &A, 84 SDValue &B, SDValue &C, 85 bool CheckProfitability = true); 86 bool SelectImmShifterOperand(SDValue N, SDValue &A, 87 SDValue &B, bool CheckProfitability = true); 88 bool SelectShiftRegShifterOperand(SDValue N, SDValue &A, 89 SDValue &B, SDValue &C) { 90 // Don't apply the profitability check 91 return SelectRegShifterOperand(N, A, B, C, false); 92 } 93 bool SelectShiftImmShifterOperand(SDValue N, SDValue &A, 94 SDValue &B) { 95 // Don't apply the profitability check 96 return SelectImmShifterOperand(N, A, B, false); 97 } 98 99 bool SelectAddLikeOr(SDNode *Parent, SDValue N, SDValue &Out); 100 101 bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); 102 bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc); 103 104 bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) { 105 const ConstantSDNode *CN = cast<ConstantSDNode>(N); 106 Pred = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(N), MVT::i32); 107 Reg = CurDAG->getRegister(ARM::CPSR, MVT::i32); 108 return true; 109 } 110 111 bool SelectAddrMode2OffsetReg(SDNode *Op, SDValue N, 112 SDValue &Offset, SDValue &Opc); 113 bool SelectAddrMode2OffsetImm(SDNode *Op, SDValue N, 114 SDValue &Offset, SDValue &Opc); 115 bool SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N, 116 SDValue &Offset, SDValue &Opc); 117 bool SelectAddrOffsetNone(SDValue N, SDValue &Base); 118 bool SelectAddrMode3(SDValue N, SDValue &Base, 119 SDValue &Offset, SDValue &Opc); 120 bool SelectAddrMode3Offset(SDNode *Op, SDValue N, 121 SDValue &Offset, SDValue &Opc); 122 bool IsAddressingMode5(SDValue N, SDValue &Base, SDValue &Offset, bool FP16); 123 bool SelectAddrMode5(SDValue N, SDValue &Base, SDValue &Offset); 124 bool SelectAddrMode5FP16(SDValue N, SDValue &Base, SDValue &Offset); 125 bool SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr,SDValue &Align); 126 bool SelectAddrMode6Offset(SDNode *Op, SDValue N, SDValue &Offset); 127 128 bool SelectAddrModePC(SDValue N, SDValue &Offset, SDValue &Label); 129 130 // Thumb Addressing Modes: 131 bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset); 132 bool SelectThumbAddrModeRRSext(SDValue N, SDValue &Base, SDValue &Offset); 133 bool SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, SDValue &Base, 134 SDValue &OffImm); 135 bool SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base, 136 SDValue &OffImm); 137 bool SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base, 138 SDValue &OffImm); 139 bool SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base, 140 SDValue &OffImm); 141 bool SelectThumbAddrModeSP(SDValue N, SDValue &Base, SDValue &OffImm); 142 template <unsigned Shift> 143 bool SelectTAddrModeImm7(SDValue N, SDValue &Base, SDValue &OffImm); 144 145 // Thumb 2 Addressing Modes: 146 bool SelectT2AddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); 147 bool SelectT2AddrModeImm8(SDValue N, SDValue &Base, 148 SDValue &OffImm); 149 bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 150 SDValue &OffImm); 151 template <unsigned Shift> 152 bool SelectT2AddrModeImm7Offset(SDNode *Op, SDValue N, SDValue &OffImm); 153 bool SelectT2AddrModeImm7Offset(SDNode *Op, SDValue N, SDValue &OffImm, 154 unsigned Shift); 155 template <unsigned Shift> 156 bool SelectT2AddrModeImm7(SDValue N, SDValue &Base, SDValue &OffImm); 157 bool SelectT2AddrModeSoReg(SDValue N, SDValue &Base, 158 SDValue &OffReg, SDValue &ShImm); 159 bool SelectT2AddrModeExclusive(SDValue N, SDValue &Base, SDValue &OffImm); 160 161 inline bool is_so_imm(unsigned Imm) const { 162 return ARM_AM::getSOImmVal(Imm) != -1; 163 } 164 165 inline bool is_so_imm_not(unsigned Imm) const { 166 return ARM_AM::getSOImmVal(~Imm) != -1; 167 } 168 169 inline bool is_t2_so_imm(unsigned Imm) const { 170 return ARM_AM::getT2SOImmVal(Imm) != -1; 171 } 172 173 inline bool is_t2_so_imm_not(unsigned Imm) const { 174 return ARM_AM::getT2SOImmVal(~Imm) != -1; 175 } 176 177 // Include the pieces autogenerated from the target description. 178 #include "ARMGenDAGISel.inc" 179 180 private: 181 void transferMemOperands(SDNode *Src, SDNode *Dst); 182 183 /// Indexed (pre/post inc/dec) load matching code for ARM. 184 bool tryARMIndexedLoad(SDNode *N); 185 bool tryT1IndexedLoad(SDNode *N); 186 bool tryT2IndexedLoad(SDNode *N); 187 bool tryMVEIndexedLoad(SDNode *N); 188 189 /// SelectVLD - Select NEON load intrinsics. NumVecs should be 190 /// 1, 2, 3 or 4. The opcode arrays specify the instructions used for 191 /// loads of D registers and even subregs and odd subregs of Q registers. 192 /// For NumVecs <= 2, QOpcodes1 is not used. 193 void SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs, 194 const uint16_t *DOpcodes, const uint16_t *QOpcodes0, 195 const uint16_t *QOpcodes1); 196 197 /// SelectVST - Select NEON store intrinsics. NumVecs should 198 /// be 1, 2, 3 or 4. The opcode arrays specify the instructions used for 199 /// stores of D registers and even subregs and odd subregs of Q registers. 200 /// For NumVecs <= 2, QOpcodes1 is not used. 201 void SelectVST(SDNode *N, bool isUpdating, unsigned NumVecs, 202 const uint16_t *DOpcodes, const uint16_t *QOpcodes0, 203 const uint16_t *QOpcodes1); 204 205 /// SelectVLDSTLane - Select NEON load/store lane intrinsics. NumVecs should 206 /// be 2, 3 or 4. The opcode arrays specify the instructions used for 207 /// load/store of D registers and Q registers. 208 void SelectVLDSTLane(SDNode *N, bool IsLoad, bool isUpdating, 209 unsigned NumVecs, const uint16_t *DOpcodes, 210 const uint16_t *QOpcodes); 211 212 /// Helper functions for setting up clusters of MVE predication operands. 213 template <typename SDValueVector> 214 void AddMVEPredicateToOps(SDValueVector &Ops, SDLoc Loc, 215 SDValue PredicateMask); 216 template <typename SDValueVector> 217 void AddMVEPredicateToOps(SDValueVector &Ops, SDLoc Loc, 218 SDValue PredicateMask, SDValue Inactive); 219 220 template <typename SDValueVector> 221 void AddEmptyMVEPredicateToOps(SDValueVector &Ops, SDLoc Loc); 222 template <typename SDValueVector> 223 void AddEmptyMVEPredicateToOps(SDValueVector &Ops, SDLoc Loc, EVT InactiveTy); 224 225 /// SelectMVE_WB - Select MVE writeback load/store intrinsics. 226 void SelectMVE_WB(SDNode *N, const uint16_t *Opcodes, bool Predicated); 227 228 /// SelectMVE_LongShift - Select MVE 64-bit scalar shift intrinsics. 229 void SelectMVE_LongShift(SDNode *N, uint16_t Opcode, bool Immediate); 230 231 /// SelectMVE_VADCSBC - Select MVE vector add/sub-with-carry intrinsics. 232 void SelectMVE_VADCSBC(SDNode *N, uint16_t OpcodeWithCarry, 233 uint16_t OpcodeWithNoCarry, bool Add, bool Predicated); 234 235 /// SelectMVE_VLD - Select MVE interleaving load intrinsics. NumVecs 236 /// should be 2 or 4. The opcode array specifies the instructions 237 /// used for 8, 16 and 32-bit lane sizes respectively, and each 238 /// pointer points to a set of NumVecs sub-opcodes used for the 239 /// different stages (e.g. VLD20 versus VLD21) of each load family. 240 void SelectMVE_VLD(SDNode *N, unsigned NumVecs, 241 const uint16_t *const *Opcodes); 242 243 /// SelectVLDDup - Select NEON load-duplicate intrinsics. NumVecs 244 /// should be 1, 2, 3 or 4. The opcode array specifies the instructions used 245 /// for loading D registers. 246 void SelectVLDDup(SDNode *N, bool IsIntrinsic, bool isUpdating, 247 unsigned NumVecs, const uint16_t *DOpcodes, 248 const uint16_t *QOpcodes0 = nullptr, 249 const uint16_t *QOpcodes1 = nullptr); 250 251 /// Try to select SBFX/UBFX instructions for ARM. 252 bool tryV6T2BitfieldExtractOp(SDNode *N, bool isSigned); 253 254 // Select special operations if node forms integer ABS pattern 255 bool tryABSOp(SDNode *N); 256 257 bool tryReadRegister(SDNode *N); 258 bool tryWriteRegister(SDNode *N); 259 260 bool tryInlineAsm(SDNode *N); 261 262 void SelectCMPZ(SDNode *N, bool &SwitchEQNEToPLMI); 263 264 void SelectCMP_SWAP(SDNode *N); 265 266 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 267 /// inline asm expressions. 268 bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 269 std::vector<SDValue> &OutOps) override; 270 271 // Form pairs of consecutive R, S, D, or Q registers. 272 SDNode *createGPRPairNode(EVT VT, SDValue V0, SDValue V1); 273 SDNode *createSRegPairNode(EVT VT, SDValue V0, SDValue V1); 274 SDNode *createDRegPairNode(EVT VT, SDValue V0, SDValue V1); 275 SDNode *createQRegPairNode(EVT VT, SDValue V0, SDValue V1); 276 277 // Form sequences of 4 consecutive S, D, or Q registers. 278 SDNode *createQuadSRegsNode(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3); 279 SDNode *createQuadDRegsNode(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3); 280 SDNode *createQuadQRegsNode(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3); 281 282 // Get the alignment operand for a NEON VLD or VST instruction. 283 SDValue GetVLDSTAlign(SDValue Align, const SDLoc &dl, unsigned NumVecs, 284 bool is64BitVector); 285 286 /// Checks if N is a multiplication by a constant where we can extract out a 287 /// power of two from the constant so that it can be used in a shift, but only 288 /// if it simplifies the materialization of the constant. Returns true if it 289 /// is, and assigns to PowerOfTwo the power of two that should be extracted 290 /// out and to NewMulConst the new constant to be multiplied by. 291 bool canExtractShiftFromMul(const SDValue &N, unsigned MaxShift, 292 unsigned &PowerOfTwo, SDValue &NewMulConst) const; 293 294 /// Replace N with M in CurDAG, in a way that also ensures that M gets 295 /// selected when N would have been selected. 296 void replaceDAGValue(const SDValue &N, SDValue M); 297 }; 298 } 299 300 /// isInt32Immediate - This method tests to see if the node is a 32-bit constant 301 /// operand. If so Imm will receive the 32-bit value. 302 static bool isInt32Immediate(SDNode *N, unsigned &Imm) { 303 if (N->getOpcode() == ISD::Constant && N->getValueType(0) == MVT::i32) { 304 Imm = cast<ConstantSDNode>(N)->getZExtValue(); 305 return true; 306 } 307 return false; 308 } 309 310 // isInt32Immediate - This method tests to see if a constant operand. 311 // If so Imm will receive the 32 bit value. 312 static bool isInt32Immediate(SDValue N, unsigned &Imm) { 313 return isInt32Immediate(N.getNode(), Imm); 314 } 315 316 // isOpcWithIntImmediate - This method tests to see if the node is a specific 317 // opcode and that it has a immediate integer right operand. 318 // If so Imm will receive the 32 bit value. 319 static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) { 320 return N->getOpcode() == Opc && 321 isInt32Immediate(N->getOperand(1).getNode(), Imm); 322 } 323 324 /// Check whether a particular node is a constant value representable as 325 /// (N * Scale) where (N in [\p RangeMin, \p RangeMax). 326 /// 327 /// \param ScaledConstant [out] - On success, the pre-scaled constant value. 328 static bool isScaledConstantInRange(SDValue Node, int Scale, 329 int RangeMin, int RangeMax, 330 int &ScaledConstant) { 331 assert(Scale > 0 && "Invalid scale!"); 332 333 // Check that this is a constant. 334 const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Node); 335 if (!C) 336 return false; 337 338 ScaledConstant = (int) C->getZExtValue(); 339 if ((ScaledConstant % Scale) != 0) 340 return false; 341 342 ScaledConstant /= Scale; 343 return ScaledConstant >= RangeMin && ScaledConstant < RangeMax; 344 } 345 346 void ARMDAGToDAGISel::PreprocessISelDAG() { 347 if (!Subtarget->hasV6T2Ops()) 348 return; 349 350 bool isThumb2 = Subtarget->isThumb(); 351 for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(), 352 E = CurDAG->allnodes_end(); I != E; ) { 353 SDNode *N = &*I++; // Preincrement iterator to avoid invalidation issues. 354 355 if (N->getOpcode() != ISD::ADD) 356 continue; 357 358 // Look for (add X1, (and (srl X2, c1), c2)) where c2 is constant with 359 // leading zeros, followed by consecutive set bits, followed by 1 or 2 360 // trailing zeros, e.g. 1020. 361 // Transform the expression to 362 // (add X1, (shl (and (srl X2, c1), (c2>>tz)), tz)) where tz is the number 363 // of trailing zeros of c2. The left shift would be folded as an shifter 364 // operand of 'add' and the 'and' and 'srl' would become a bits extraction 365 // node (UBFX). 366 367 SDValue N0 = N->getOperand(0); 368 SDValue N1 = N->getOperand(1); 369 unsigned And_imm = 0; 370 if (!isOpcWithIntImmediate(N1.getNode(), ISD::AND, And_imm)) { 371 if (isOpcWithIntImmediate(N0.getNode(), ISD::AND, And_imm)) 372 std::swap(N0, N1); 373 } 374 if (!And_imm) 375 continue; 376 377 // Check if the AND mask is an immediate of the form: 000.....1111111100 378 unsigned TZ = countTrailingZeros(And_imm); 379 if (TZ != 1 && TZ != 2) 380 // Be conservative here. Shifter operands aren't always free. e.g. On 381 // Swift, left shifter operand of 1 / 2 for free but others are not. 382 // e.g. 383 // ubfx r3, r1, #16, #8 384 // ldr.w r3, [r0, r3, lsl #2] 385 // vs. 386 // mov.w r9, #1020 387 // and.w r2, r9, r1, lsr #14 388 // ldr r2, [r0, r2] 389 continue; 390 And_imm >>= TZ; 391 if (And_imm & (And_imm + 1)) 392 continue; 393 394 // Look for (and (srl X, c1), c2). 395 SDValue Srl = N1.getOperand(0); 396 unsigned Srl_imm = 0; 397 if (!isOpcWithIntImmediate(Srl.getNode(), ISD::SRL, Srl_imm) || 398 (Srl_imm <= 2)) 399 continue; 400 401 // Make sure first operand is not a shifter operand which would prevent 402 // folding of the left shift. 403 SDValue CPTmp0; 404 SDValue CPTmp1; 405 SDValue CPTmp2; 406 if (isThumb2) { 407 if (SelectImmShifterOperand(N0, CPTmp0, CPTmp1)) 408 continue; 409 } else { 410 if (SelectImmShifterOperand(N0, CPTmp0, CPTmp1) || 411 SelectRegShifterOperand(N0, CPTmp0, CPTmp1, CPTmp2)) 412 continue; 413 } 414 415 // Now make the transformation. 416 Srl = CurDAG->getNode(ISD::SRL, SDLoc(Srl), MVT::i32, 417 Srl.getOperand(0), 418 CurDAG->getConstant(Srl_imm + TZ, SDLoc(Srl), 419 MVT::i32)); 420 N1 = CurDAG->getNode(ISD::AND, SDLoc(N1), MVT::i32, 421 Srl, 422 CurDAG->getConstant(And_imm, SDLoc(Srl), MVT::i32)); 423 N1 = CurDAG->getNode(ISD::SHL, SDLoc(N1), MVT::i32, 424 N1, CurDAG->getConstant(TZ, SDLoc(Srl), MVT::i32)); 425 CurDAG->UpdateNodeOperands(N, N0, N1); 426 } 427 } 428 429 /// hasNoVMLxHazardUse - Return true if it's desirable to select a FP MLA / MLS 430 /// node. VFP / NEON fp VMLA / VMLS instructions have special RAW hazards (at 431 /// least on current ARM implementations) which should be avoidded. 432 bool ARMDAGToDAGISel::hasNoVMLxHazardUse(SDNode *N) const { 433 if (OptLevel == CodeGenOpt::None) 434 return true; 435 436 if (!Subtarget->hasVMLxHazards()) 437 return true; 438 439 if (!N->hasOneUse()) 440 return false; 441 442 SDNode *Use = *N->use_begin(); 443 if (Use->getOpcode() == ISD::CopyToReg) 444 return true; 445 if (Use->isMachineOpcode()) { 446 const ARMBaseInstrInfo *TII = static_cast<const ARMBaseInstrInfo *>( 447 CurDAG->getSubtarget().getInstrInfo()); 448 449 const MCInstrDesc &MCID = TII->get(Use->getMachineOpcode()); 450 if (MCID.mayStore()) 451 return true; 452 unsigned Opcode = MCID.getOpcode(); 453 if (Opcode == ARM::VMOVRS || Opcode == ARM::VMOVRRD) 454 return true; 455 // vmlx feeding into another vmlx. We actually want to unfold 456 // the use later in the MLxExpansion pass. e.g. 457 // vmla 458 // vmla (stall 8 cycles) 459 // 460 // vmul (5 cycles) 461 // vadd (5 cycles) 462 // vmla 463 // This adds up to about 18 - 19 cycles. 464 // 465 // vmla 466 // vmul (stall 4 cycles) 467 // vadd adds up to about 14 cycles. 468 return TII->isFpMLxInstruction(Opcode); 469 } 470 471 return false; 472 } 473 474 bool ARMDAGToDAGISel::isShifterOpProfitable(const SDValue &Shift, 475 ARM_AM::ShiftOpc ShOpcVal, 476 unsigned ShAmt) { 477 if (!Subtarget->isLikeA9() && !Subtarget->isSwift()) 478 return true; 479 if (Shift.hasOneUse()) 480 return true; 481 // R << 2 is free. 482 return ShOpcVal == ARM_AM::lsl && 483 (ShAmt == 2 || (Subtarget->isSwift() && ShAmt == 1)); 484 } 485 486 bool ARMDAGToDAGISel::canExtractShiftFromMul(const SDValue &N, 487 unsigned MaxShift, 488 unsigned &PowerOfTwo, 489 SDValue &NewMulConst) const { 490 assert(N.getOpcode() == ISD::MUL); 491 assert(MaxShift > 0); 492 493 // If the multiply is used in more than one place then changing the constant 494 // will make other uses incorrect, so don't. 495 if (!N.hasOneUse()) return false; 496 // Check if the multiply is by a constant 497 ConstantSDNode *MulConst = dyn_cast<ConstantSDNode>(N.getOperand(1)); 498 if (!MulConst) return false; 499 // If the constant is used in more than one place then modifying it will mean 500 // we need to materialize two constants instead of one, which is a bad idea. 501 if (!MulConst->hasOneUse()) return false; 502 unsigned MulConstVal = MulConst->getZExtValue(); 503 if (MulConstVal == 0) return false; 504 505 // Find the largest power of 2 that MulConstVal is a multiple of 506 PowerOfTwo = MaxShift; 507 while ((MulConstVal % (1 << PowerOfTwo)) != 0) { 508 --PowerOfTwo; 509 if (PowerOfTwo == 0) return false; 510 } 511 512 // Only optimise if the new cost is better 513 unsigned NewMulConstVal = MulConstVal / (1 << PowerOfTwo); 514 NewMulConst = CurDAG->getConstant(NewMulConstVal, SDLoc(N), MVT::i32); 515 unsigned OldCost = ConstantMaterializationCost(MulConstVal, Subtarget); 516 unsigned NewCost = ConstantMaterializationCost(NewMulConstVal, Subtarget); 517 return NewCost < OldCost; 518 } 519 520 void ARMDAGToDAGISel::replaceDAGValue(const SDValue &N, SDValue M) { 521 CurDAG->RepositionNode(N.getNode()->getIterator(), M.getNode()); 522 ReplaceUses(N, M); 523 } 524 525 bool ARMDAGToDAGISel::SelectImmShifterOperand(SDValue N, 526 SDValue &BaseReg, 527 SDValue &Opc, 528 bool CheckProfitability) { 529 if (DisableShifterOp) 530 return false; 531 532 // If N is a multiply-by-constant and it's profitable to extract a shift and 533 // use it in a shifted operand do so. 534 if (N.getOpcode() == ISD::MUL) { 535 unsigned PowerOfTwo = 0; 536 SDValue NewMulConst; 537 if (canExtractShiftFromMul(N, 31, PowerOfTwo, NewMulConst)) { 538 HandleSDNode Handle(N); 539 SDLoc Loc(N); 540 replaceDAGValue(N.getOperand(1), NewMulConst); 541 BaseReg = Handle.getValue(); 542 Opc = CurDAG->getTargetConstant( 543 ARM_AM::getSORegOpc(ARM_AM::lsl, PowerOfTwo), Loc, MVT::i32); 544 return true; 545 } 546 } 547 548 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); 549 550 // Don't match base register only case. That is matched to a separate 551 // lower complexity pattern with explicit register operand. 552 if (ShOpcVal == ARM_AM::no_shift) return false; 553 554 BaseReg = N.getOperand(0); 555 unsigned ShImmVal = 0; 556 ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1)); 557 if (!RHS) return false; 558 ShImmVal = RHS->getZExtValue() & 31; 559 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 560 SDLoc(N), MVT::i32); 561 return true; 562 } 563 564 bool ARMDAGToDAGISel::SelectRegShifterOperand(SDValue N, 565 SDValue &BaseReg, 566 SDValue &ShReg, 567 SDValue &Opc, 568 bool CheckProfitability) { 569 if (DisableShifterOp) 570 return false; 571 572 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); 573 574 // Don't match base register only case. That is matched to a separate 575 // lower complexity pattern with explicit register operand. 576 if (ShOpcVal == ARM_AM::no_shift) return false; 577 578 BaseReg = N.getOperand(0); 579 unsigned ShImmVal = 0; 580 ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1)); 581 if (RHS) return false; 582 583 ShReg = N.getOperand(1); 584 if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal)) 585 return false; 586 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 587 SDLoc(N), MVT::i32); 588 return true; 589 } 590 591 // Determine whether an ISD::OR's operands are suitable to turn the operation 592 // into an addition, which often has more compact encodings. 593 bool ARMDAGToDAGISel::SelectAddLikeOr(SDNode *Parent, SDValue N, SDValue &Out) { 594 assert(Parent->getOpcode() == ISD::OR && "unexpected parent"); 595 Out = N; 596 return CurDAG->haveNoCommonBitsSet(N, Parent->getOperand(1)); 597 } 598 599 600 bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N, 601 SDValue &Base, 602 SDValue &OffImm) { 603 // Match simple R + imm12 operands. 604 605 // Base only. 606 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && 607 !CurDAG->isBaseWithConstantOffset(N)) { 608 if (N.getOpcode() == ISD::FrameIndex) { 609 // Match frame index. 610 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 611 Base = CurDAG->getTargetFrameIndex( 612 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 613 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 614 return true; 615 } 616 617 if (N.getOpcode() == ARMISD::Wrapper && 618 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress && 619 N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol && 620 N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) { 621 Base = N.getOperand(0); 622 } else 623 Base = N; 624 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 625 return true; 626 } 627 628 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 629 int RHSC = (int)RHS->getSExtValue(); 630 if (N.getOpcode() == ISD::SUB) 631 RHSC = -RHSC; 632 633 if (RHSC > -0x1000 && RHSC < 0x1000) { // 12 bits 634 Base = N.getOperand(0); 635 if (Base.getOpcode() == ISD::FrameIndex) { 636 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 637 Base = CurDAG->getTargetFrameIndex( 638 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 639 } 640 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 641 return true; 642 } 643 } 644 645 // Base only. 646 Base = N; 647 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 648 return true; 649 } 650 651 652 653 bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, 654 SDValue &Opc) { 655 if (N.getOpcode() == ISD::MUL && 656 ((!Subtarget->isLikeA9() && !Subtarget->isSwift()) || N.hasOneUse())) { 657 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 658 // X * [3,5,9] -> X + X * [2,4,8] etc. 659 int RHSC = (int)RHS->getZExtValue(); 660 if (RHSC & 1) { 661 RHSC = RHSC & ~1; 662 ARM_AM::AddrOpc AddSub = ARM_AM::add; 663 if (RHSC < 0) { 664 AddSub = ARM_AM::sub; 665 RHSC = - RHSC; 666 } 667 if (isPowerOf2_32(RHSC)) { 668 unsigned ShAmt = Log2_32(RHSC); 669 Base = Offset = N.getOperand(0); 670 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, 671 ARM_AM::lsl), 672 SDLoc(N), MVT::i32); 673 return true; 674 } 675 } 676 } 677 } 678 679 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && 680 // ISD::OR that is equivalent to an ISD::ADD. 681 !CurDAG->isBaseWithConstantOffset(N)) 682 return false; 683 684 // Leave simple R +/- imm12 operands for LDRi12 685 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) { 686 int RHSC; 687 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/1, 688 -0x1000+1, 0x1000, RHSC)) // 12 bits. 689 return false; 690 } 691 692 // Otherwise this is R +/- [possibly shifted] R. 693 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::SUB ? ARM_AM::sub:ARM_AM::add; 694 ARM_AM::ShiftOpc ShOpcVal = 695 ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode()); 696 unsigned ShAmt = 0; 697 698 Base = N.getOperand(0); 699 Offset = N.getOperand(1); 700 701 if (ShOpcVal != ARM_AM::no_shift) { 702 // Check to see if the RHS of the shift is a constant, if not, we can't fold 703 // it. 704 if (ConstantSDNode *Sh = 705 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) { 706 ShAmt = Sh->getZExtValue(); 707 if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt)) 708 Offset = N.getOperand(1).getOperand(0); 709 else { 710 ShAmt = 0; 711 ShOpcVal = ARM_AM::no_shift; 712 } 713 } else { 714 ShOpcVal = ARM_AM::no_shift; 715 } 716 } 717 718 // Try matching (R shl C) + (R). 719 if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift && 720 !(Subtarget->isLikeA9() || Subtarget->isSwift() || 721 N.getOperand(0).hasOneUse())) { 722 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode()); 723 if (ShOpcVal != ARM_AM::no_shift) { 724 // Check to see if the RHS of the shift is a constant, if not, we can't 725 // fold it. 726 if (ConstantSDNode *Sh = 727 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) { 728 ShAmt = Sh->getZExtValue(); 729 if (isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt)) { 730 Offset = N.getOperand(0).getOperand(0); 731 Base = N.getOperand(1); 732 } else { 733 ShAmt = 0; 734 ShOpcVal = ARM_AM::no_shift; 735 } 736 } else { 737 ShOpcVal = ARM_AM::no_shift; 738 } 739 } 740 } 741 742 // If Offset is a multiply-by-constant and it's profitable to extract a shift 743 // and use it in a shifted operand do so. 744 if (Offset.getOpcode() == ISD::MUL && N.hasOneUse()) { 745 unsigned PowerOfTwo = 0; 746 SDValue NewMulConst; 747 if (canExtractShiftFromMul(Offset, 31, PowerOfTwo, NewMulConst)) { 748 HandleSDNode Handle(Offset); 749 replaceDAGValue(Offset.getOperand(1), NewMulConst); 750 Offset = Handle.getValue(); 751 ShAmt = PowerOfTwo; 752 ShOpcVal = ARM_AM::lsl; 753 } 754 } 755 756 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 757 SDLoc(N), MVT::i32); 758 return true; 759 } 760 761 bool ARMDAGToDAGISel::SelectAddrMode2OffsetReg(SDNode *Op, SDValue N, 762 SDValue &Offset, SDValue &Opc) { 763 unsigned Opcode = Op->getOpcode(); 764 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 765 ? cast<LoadSDNode>(Op)->getAddressingMode() 766 : cast<StoreSDNode>(Op)->getAddressingMode(); 767 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 768 ? ARM_AM::add : ARM_AM::sub; 769 int Val; 770 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) 771 return false; 772 773 Offset = N; 774 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); 775 unsigned ShAmt = 0; 776 if (ShOpcVal != ARM_AM::no_shift) { 777 // Check to see if the RHS of the shift is a constant, if not, we can't fold 778 // it. 779 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 780 ShAmt = Sh->getZExtValue(); 781 if (isShifterOpProfitable(N, ShOpcVal, ShAmt)) 782 Offset = N.getOperand(0); 783 else { 784 ShAmt = 0; 785 ShOpcVal = ARM_AM::no_shift; 786 } 787 } else { 788 ShOpcVal = ARM_AM::no_shift; 789 } 790 } 791 792 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 793 SDLoc(N), MVT::i32); 794 return true; 795 } 796 797 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N, 798 SDValue &Offset, SDValue &Opc) { 799 unsigned Opcode = Op->getOpcode(); 800 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 801 ? cast<LoadSDNode>(Op)->getAddressingMode() 802 : cast<StoreSDNode>(Op)->getAddressingMode(); 803 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 804 ? ARM_AM::add : ARM_AM::sub; 805 int Val; 806 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits. 807 if (AddSub == ARM_AM::sub) Val *= -1; 808 Offset = CurDAG->getRegister(0, MVT::i32); 809 Opc = CurDAG->getTargetConstant(Val, SDLoc(Op), MVT::i32); 810 return true; 811 } 812 813 return false; 814 } 815 816 817 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImm(SDNode *Op, SDValue N, 818 SDValue &Offset, SDValue &Opc) { 819 unsigned Opcode = Op->getOpcode(); 820 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 821 ? cast<LoadSDNode>(Op)->getAddressingMode() 822 : cast<StoreSDNode>(Op)->getAddressingMode(); 823 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 824 ? ARM_AM::add : ARM_AM::sub; 825 int Val; 826 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits. 827 Offset = CurDAG->getRegister(0, MVT::i32); 828 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, 829 ARM_AM::no_shift), 830 SDLoc(Op), MVT::i32); 831 return true; 832 } 833 834 return false; 835 } 836 837 bool ARMDAGToDAGISel::SelectAddrOffsetNone(SDValue N, SDValue &Base) { 838 Base = N; 839 return true; 840 } 841 842 bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N, 843 SDValue &Base, SDValue &Offset, 844 SDValue &Opc) { 845 if (N.getOpcode() == ISD::SUB) { 846 // X - C is canonicalize to X + -C, no need to handle it here. 847 Base = N.getOperand(0); 848 Offset = N.getOperand(1); 849 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0), SDLoc(N), 850 MVT::i32); 851 return true; 852 } 853 854 if (!CurDAG->isBaseWithConstantOffset(N)) { 855 Base = N; 856 if (N.getOpcode() == ISD::FrameIndex) { 857 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 858 Base = CurDAG->getTargetFrameIndex( 859 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 860 } 861 Offset = CurDAG->getRegister(0, MVT::i32); 862 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), SDLoc(N), 863 MVT::i32); 864 return true; 865 } 866 867 // If the RHS is +/- imm8, fold into addr mode. 868 int RHSC; 869 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/1, 870 -256 + 1, 256, RHSC)) { // 8 bits. 871 Base = N.getOperand(0); 872 if (Base.getOpcode() == ISD::FrameIndex) { 873 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 874 Base = CurDAG->getTargetFrameIndex( 875 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 876 } 877 Offset = CurDAG->getRegister(0, MVT::i32); 878 879 ARM_AM::AddrOpc AddSub = ARM_AM::add; 880 if (RHSC < 0) { 881 AddSub = ARM_AM::sub; 882 RHSC = -RHSC; 883 } 884 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC), SDLoc(N), 885 MVT::i32); 886 return true; 887 } 888 889 Base = N.getOperand(0); 890 Offset = N.getOperand(1); 891 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), SDLoc(N), 892 MVT::i32); 893 return true; 894 } 895 896 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N, 897 SDValue &Offset, SDValue &Opc) { 898 unsigned Opcode = Op->getOpcode(); 899 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 900 ? cast<LoadSDNode>(Op)->getAddressingMode() 901 : cast<StoreSDNode>(Op)->getAddressingMode(); 902 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 903 ? ARM_AM::add : ARM_AM::sub; 904 int Val; 905 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 256, Val)) { // 12 bits. 906 Offset = CurDAG->getRegister(0, MVT::i32); 907 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), SDLoc(Op), 908 MVT::i32); 909 return true; 910 } 911 912 Offset = N; 913 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), SDLoc(Op), 914 MVT::i32); 915 return true; 916 } 917 918 bool ARMDAGToDAGISel::IsAddressingMode5(SDValue N, SDValue &Base, SDValue &Offset, 919 bool FP16) { 920 if (!CurDAG->isBaseWithConstantOffset(N)) { 921 Base = N; 922 if (N.getOpcode() == ISD::FrameIndex) { 923 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 924 Base = CurDAG->getTargetFrameIndex( 925 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 926 } else if (N.getOpcode() == ARMISD::Wrapper && 927 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress && 928 N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol && 929 N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) { 930 Base = N.getOperand(0); 931 } 932 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 933 SDLoc(N), MVT::i32); 934 return true; 935 } 936 937 // If the RHS is +/- imm8, fold into addr mode. 938 int RHSC; 939 const int Scale = FP16 ? 2 : 4; 940 941 if (isScaledConstantInRange(N.getOperand(1), Scale, -255, 256, RHSC)) { 942 Base = N.getOperand(0); 943 if (Base.getOpcode() == ISD::FrameIndex) { 944 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 945 Base = CurDAG->getTargetFrameIndex( 946 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 947 } 948 949 ARM_AM::AddrOpc AddSub = ARM_AM::add; 950 if (RHSC < 0) { 951 AddSub = ARM_AM::sub; 952 RHSC = -RHSC; 953 } 954 955 if (FP16) 956 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5FP16Opc(AddSub, RHSC), 957 SDLoc(N), MVT::i32); 958 else 959 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC), 960 SDLoc(N), MVT::i32); 961 962 return true; 963 } 964 965 Base = N; 966 967 if (FP16) 968 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5FP16Opc(ARM_AM::add, 0), 969 SDLoc(N), MVT::i32); 970 else 971 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 972 SDLoc(N), MVT::i32); 973 974 return true; 975 } 976 977 bool ARMDAGToDAGISel::SelectAddrMode5(SDValue N, 978 SDValue &Base, SDValue &Offset) { 979 return IsAddressingMode5(N, Base, Offset, /*FP16=*/ false); 980 } 981 982 bool ARMDAGToDAGISel::SelectAddrMode5FP16(SDValue N, 983 SDValue &Base, SDValue &Offset) { 984 return IsAddressingMode5(N, Base, Offset, /*FP16=*/ true); 985 } 986 987 bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr, 988 SDValue &Align) { 989 Addr = N; 990 991 unsigned Alignment = 0; 992 993 MemSDNode *MemN = cast<MemSDNode>(Parent); 994 995 if (isa<LSBaseSDNode>(MemN) || 996 ((MemN->getOpcode() == ARMISD::VST1_UPD || 997 MemN->getOpcode() == ARMISD::VLD1_UPD) && 998 MemN->getConstantOperandVal(MemN->getNumOperands() - 1) == 1)) { 999 // This case occurs only for VLD1-lane/dup and VST1-lane instructions. 1000 // The maximum alignment is equal to the memory size being referenced. 1001 unsigned MMOAlign = MemN->getAlignment(); 1002 unsigned MemSize = MemN->getMemoryVT().getSizeInBits() / 8; 1003 if (MMOAlign >= MemSize && MemSize > 1) 1004 Alignment = MemSize; 1005 } else { 1006 // All other uses of addrmode6 are for intrinsics. For now just record 1007 // the raw alignment value; it will be refined later based on the legal 1008 // alignment operands for the intrinsic. 1009 Alignment = MemN->getAlignment(); 1010 } 1011 1012 Align = CurDAG->getTargetConstant(Alignment, SDLoc(N), MVT::i32); 1013 return true; 1014 } 1015 1016 bool ARMDAGToDAGISel::SelectAddrMode6Offset(SDNode *Op, SDValue N, 1017 SDValue &Offset) { 1018 LSBaseSDNode *LdSt = cast<LSBaseSDNode>(Op); 1019 ISD::MemIndexedMode AM = LdSt->getAddressingMode(); 1020 if (AM != ISD::POST_INC) 1021 return false; 1022 Offset = N; 1023 if (ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N)) { 1024 if (NC->getZExtValue() * 8 == LdSt->getMemoryVT().getSizeInBits()) 1025 Offset = CurDAG->getRegister(0, MVT::i32); 1026 } 1027 return true; 1028 } 1029 1030 bool ARMDAGToDAGISel::SelectAddrModePC(SDValue N, 1031 SDValue &Offset, SDValue &Label) { 1032 if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { 1033 Offset = N.getOperand(0); 1034 SDValue N1 = N.getOperand(1); 1035 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(), 1036 SDLoc(N), MVT::i32); 1037 return true; 1038 } 1039 1040 return false; 1041 } 1042 1043 1044 //===----------------------------------------------------------------------===// 1045 // Thumb Addressing Modes 1046 //===----------------------------------------------------------------------===// 1047 1048 static bool shouldUseZeroOffsetLdSt(SDValue N) { 1049 // Negative numbers are difficult to materialise in thumb1. If we are 1050 // selecting the add of a negative, instead try to select ri with a zero 1051 // offset, so create the add node directly which will become a sub. 1052 if (N.getOpcode() != ISD::ADD) 1053 return false; 1054 1055 // Look for an imm which is not legal for ld/st, but is legal for sub. 1056 if (auto C = dyn_cast<ConstantSDNode>(N.getOperand(1))) 1057 return C->getSExtValue() < 0 && C->getSExtValue() >= -255; 1058 1059 return false; 1060 } 1061 1062 bool ARMDAGToDAGISel::SelectThumbAddrModeRRSext(SDValue N, SDValue &Base, 1063 SDValue &Offset) { 1064 if (N.getOpcode() != ISD::ADD && !CurDAG->isBaseWithConstantOffset(N)) { 1065 ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N); 1066 if (!NC || !NC->isNullValue()) 1067 return false; 1068 1069 Base = Offset = N; 1070 return true; 1071 } 1072 1073 Base = N.getOperand(0); 1074 Offset = N.getOperand(1); 1075 return true; 1076 } 1077 1078 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N, SDValue &Base, 1079 SDValue &Offset) { 1080 if (shouldUseZeroOffsetLdSt(N)) 1081 return false; // Select ri instead 1082 return SelectThumbAddrModeRRSext(N, Base, Offset); 1083 } 1084 1085 bool 1086 ARMDAGToDAGISel::SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, 1087 SDValue &Base, SDValue &OffImm) { 1088 if (shouldUseZeroOffsetLdSt(N)) { 1089 Base = N; 1090 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1091 return true; 1092 } 1093 1094 if (!CurDAG->isBaseWithConstantOffset(N)) { 1095 if (N.getOpcode() == ISD::ADD) { 1096 return false; // We want to select register offset instead 1097 } else if (N.getOpcode() == ARMISD::Wrapper && 1098 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress && 1099 N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol && 1100 N.getOperand(0).getOpcode() != ISD::TargetConstantPool && 1101 N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) { 1102 Base = N.getOperand(0); 1103 } else { 1104 Base = N; 1105 } 1106 1107 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1108 return true; 1109 } 1110 1111 // If the RHS is + imm5 * scale, fold into addr mode. 1112 int RHSC; 1113 if (isScaledConstantInRange(N.getOperand(1), Scale, 0, 32, RHSC)) { 1114 Base = N.getOperand(0); 1115 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 1116 return true; 1117 } 1118 1119 // Offset is too large, so use register offset instead. 1120 return false; 1121 } 1122 1123 bool 1124 ARMDAGToDAGISel::SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base, 1125 SDValue &OffImm) { 1126 return SelectThumbAddrModeImm5S(N, 4, Base, OffImm); 1127 } 1128 1129 bool 1130 ARMDAGToDAGISel::SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base, 1131 SDValue &OffImm) { 1132 return SelectThumbAddrModeImm5S(N, 2, Base, OffImm); 1133 } 1134 1135 bool 1136 ARMDAGToDAGISel::SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base, 1137 SDValue &OffImm) { 1138 return SelectThumbAddrModeImm5S(N, 1, Base, OffImm); 1139 } 1140 1141 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue N, 1142 SDValue &Base, SDValue &OffImm) { 1143 if (N.getOpcode() == ISD::FrameIndex) { 1144 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1145 // Only multiples of 4 are allowed for the offset, so the frame object 1146 // alignment must be at least 4. 1147 MachineFrameInfo &MFI = MF->getFrameInfo(); 1148 if (MFI.getObjectAlignment(FI) < 4) 1149 MFI.setObjectAlignment(FI, 4); 1150 Base = CurDAG->getTargetFrameIndex( 1151 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1152 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1153 return true; 1154 } 1155 1156 if (!CurDAG->isBaseWithConstantOffset(N)) 1157 return false; 1158 1159 if (N.getOperand(0).getOpcode() == ISD::FrameIndex) { 1160 // If the RHS is + imm8 * scale, fold into addr mode. 1161 int RHSC; 1162 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/4, 0, 256, RHSC)) { 1163 Base = N.getOperand(0); 1164 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1165 // Make sure the offset is inside the object, or we might fail to 1166 // allocate an emergency spill slot. (An out-of-range access is UB, but 1167 // it could show up anyway.) 1168 MachineFrameInfo &MFI = MF->getFrameInfo(); 1169 if (RHSC * 4 < MFI.getObjectSize(FI)) { 1170 // For LHS+RHS to result in an offset that's a multiple of 4 the object 1171 // indexed by the LHS must be 4-byte aligned. 1172 if (!MFI.isFixedObjectIndex(FI) && MFI.getObjectAlignment(FI) < 4) 1173 MFI.setObjectAlignment(FI, 4); 1174 if (MFI.getObjectAlignment(FI) >= 4) { 1175 Base = CurDAG->getTargetFrameIndex( 1176 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1177 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 1178 return true; 1179 } 1180 } 1181 } 1182 } 1183 1184 return false; 1185 } 1186 1187 template <unsigned Shift> 1188 bool ARMDAGToDAGISel::SelectTAddrModeImm7(SDValue N, SDValue &Base, 1189 SDValue &OffImm) { 1190 if (N.getOpcode() == ISD::SUB || CurDAG->isBaseWithConstantOffset(N)) { 1191 int RHSC; 1192 if (isScaledConstantInRange(N.getOperand(1), 1 << Shift, -0x7f, 0x80, 1193 RHSC)) { 1194 Base = N.getOperand(0); 1195 if (N.getOpcode() == ISD::SUB) 1196 RHSC = -RHSC; 1197 OffImm = 1198 CurDAG->getTargetConstant(RHSC * (1 << Shift), SDLoc(N), MVT::i32); 1199 return true; 1200 } 1201 } 1202 1203 // Base only. 1204 Base = N; 1205 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1206 return true; 1207 } 1208 1209 1210 //===----------------------------------------------------------------------===// 1211 // Thumb 2 Addressing Modes 1212 //===----------------------------------------------------------------------===// 1213 1214 1215 bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue N, 1216 SDValue &Base, SDValue &OffImm) { 1217 // Match simple R + imm12 operands. 1218 1219 // Base only. 1220 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && 1221 !CurDAG->isBaseWithConstantOffset(N)) { 1222 if (N.getOpcode() == ISD::FrameIndex) { 1223 // Match frame index. 1224 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1225 Base = CurDAG->getTargetFrameIndex( 1226 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1227 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1228 return true; 1229 } 1230 1231 if (N.getOpcode() == ARMISD::Wrapper && 1232 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress && 1233 N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol && 1234 N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) { 1235 Base = N.getOperand(0); 1236 if (Base.getOpcode() == ISD::TargetConstantPool) 1237 return false; // We want to select t2LDRpci instead. 1238 } else 1239 Base = N; 1240 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1241 return true; 1242 } 1243 1244 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 1245 if (SelectT2AddrModeImm8(N, Base, OffImm)) 1246 // Let t2LDRi8 handle (R - imm8). 1247 return false; 1248 1249 int RHSC = (int)RHS->getZExtValue(); 1250 if (N.getOpcode() == ISD::SUB) 1251 RHSC = -RHSC; 1252 1253 if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits (unsigned) 1254 Base = N.getOperand(0); 1255 if (Base.getOpcode() == ISD::FrameIndex) { 1256 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1257 Base = CurDAG->getTargetFrameIndex( 1258 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1259 } 1260 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 1261 return true; 1262 } 1263 } 1264 1265 // Base only. 1266 Base = N; 1267 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1268 return true; 1269 } 1270 1271 bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue N, 1272 SDValue &Base, SDValue &OffImm) { 1273 // Match simple R - imm8 operands. 1274 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && 1275 !CurDAG->isBaseWithConstantOffset(N)) 1276 return false; 1277 1278 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 1279 int RHSC = (int)RHS->getSExtValue(); 1280 if (N.getOpcode() == ISD::SUB) 1281 RHSC = -RHSC; 1282 1283 if ((RHSC >= -255) && (RHSC < 0)) { // 8 bits (always negative) 1284 Base = N.getOperand(0); 1285 if (Base.getOpcode() == ISD::FrameIndex) { 1286 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1287 Base = CurDAG->getTargetFrameIndex( 1288 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1289 } 1290 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 1291 return true; 1292 } 1293 } 1294 1295 return false; 1296 } 1297 1298 bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 1299 SDValue &OffImm){ 1300 unsigned Opcode = Op->getOpcode(); 1301 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 1302 ? cast<LoadSDNode>(Op)->getAddressingMode() 1303 : cast<StoreSDNode>(Op)->getAddressingMode(); 1304 int RHSC; 1305 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x100, RHSC)) { // 8 bits. 1306 OffImm = ((AM == ISD::PRE_INC) || (AM == ISD::POST_INC)) 1307 ? CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32) 1308 : CurDAG->getTargetConstant(-RHSC, SDLoc(N), MVT::i32); 1309 return true; 1310 } 1311 1312 return false; 1313 } 1314 1315 template <unsigned Shift> 1316 bool ARMDAGToDAGISel::SelectT2AddrModeImm7(SDValue N, SDValue &Base, 1317 SDValue &OffImm) { 1318 if (N.getOpcode() == ISD::SUB || CurDAG->isBaseWithConstantOffset(N)) { 1319 int RHSC; 1320 if (isScaledConstantInRange(N.getOperand(1), 1 << Shift, -0x7f, 0x80, 1321 RHSC)) { 1322 Base = N.getOperand(0); 1323 if (Base.getOpcode() == ISD::FrameIndex) { 1324 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1325 Base = CurDAG->getTargetFrameIndex( 1326 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1327 } 1328 1329 if (N.getOpcode() == ISD::SUB) 1330 RHSC = -RHSC; 1331 OffImm = 1332 CurDAG->getTargetConstant(RHSC * (1 << Shift), SDLoc(N), MVT::i32); 1333 return true; 1334 } 1335 } 1336 1337 // Base only. 1338 Base = N; 1339 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1340 return true; 1341 } 1342 1343 template <unsigned Shift> 1344 bool ARMDAGToDAGISel::SelectT2AddrModeImm7Offset(SDNode *Op, SDValue N, 1345 SDValue &OffImm) { 1346 return SelectT2AddrModeImm7Offset(Op, N, OffImm, Shift); 1347 } 1348 1349 bool ARMDAGToDAGISel::SelectT2AddrModeImm7Offset(SDNode *Op, SDValue N, 1350 SDValue &OffImm, 1351 unsigned Shift) { 1352 unsigned Opcode = Op->getOpcode(); 1353 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 1354 ? cast<LoadSDNode>(Op)->getAddressingMode() 1355 : cast<StoreSDNode>(Op)->getAddressingMode(); 1356 int RHSC; 1357 if (isScaledConstantInRange(N, 1 << Shift, 0, 0x80, RHSC)) { // 7 bits. 1358 OffImm = 1359 ((AM == ISD::PRE_INC) || (AM == ISD::POST_INC)) 1360 ? CurDAG->getTargetConstant(RHSC * (1 << Shift), SDLoc(N), MVT::i32) 1361 : CurDAG->getTargetConstant(-RHSC * (1 << Shift), SDLoc(N), 1362 MVT::i32); 1363 return true; 1364 } 1365 return false; 1366 } 1367 1368 bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue N, 1369 SDValue &Base, 1370 SDValue &OffReg, SDValue &ShImm) { 1371 // (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12. 1372 if (N.getOpcode() != ISD::ADD && !CurDAG->isBaseWithConstantOffset(N)) 1373 return false; 1374 1375 // Leave (R + imm12) for t2LDRi12, (R - imm8) for t2LDRi8. 1376 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 1377 int RHSC = (int)RHS->getZExtValue(); 1378 if (RHSC >= 0 && RHSC < 0x1000) // 12 bits (unsigned) 1379 return false; 1380 else if (RHSC < 0 && RHSC >= -255) // 8 bits 1381 return false; 1382 } 1383 1384 // Look for (R + R) or (R + (R << [1,2,3])). 1385 unsigned ShAmt = 0; 1386 Base = N.getOperand(0); 1387 OffReg = N.getOperand(1); 1388 1389 // Swap if it is ((R << c) + R). 1390 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg.getOpcode()); 1391 if (ShOpcVal != ARM_AM::lsl) { 1392 ShOpcVal = ARM_AM::getShiftOpcForNode(Base.getOpcode()); 1393 if (ShOpcVal == ARM_AM::lsl) 1394 std::swap(Base, OffReg); 1395 } 1396 1397 if (ShOpcVal == ARM_AM::lsl) { 1398 // Check to see if the RHS of the shift is a constant, if not, we can't fold 1399 // it. 1400 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(OffReg.getOperand(1))) { 1401 ShAmt = Sh->getZExtValue(); 1402 if (ShAmt < 4 && isShifterOpProfitable(OffReg, ShOpcVal, ShAmt)) 1403 OffReg = OffReg.getOperand(0); 1404 else { 1405 ShAmt = 0; 1406 } 1407 } 1408 } 1409 1410 // If OffReg is a multiply-by-constant and it's profitable to extract a shift 1411 // and use it in a shifted operand do so. 1412 if (OffReg.getOpcode() == ISD::MUL && N.hasOneUse()) { 1413 unsigned PowerOfTwo = 0; 1414 SDValue NewMulConst; 1415 if (canExtractShiftFromMul(OffReg, 3, PowerOfTwo, NewMulConst)) { 1416 HandleSDNode Handle(OffReg); 1417 replaceDAGValue(OffReg.getOperand(1), NewMulConst); 1418 OffReg = Handle.getValue(); 1419 ShAmt = PowerOfTwo; 1420 } 1421 } 1422 1423 ShImm = CurDAG->getTargetConstant(ShAmt, SDLoc(N), MVT::i32); 1424 1425 return true; 1426 } 1427 1428 bool ARMDAGToDAGISel::SelectT2AddrModeExclusive(SDValue N, SDValue &Base, 1429 SDValue &OffImm) { 1430 // This *must* succeed since it's used for the irreplaceable ldrex and strex 1431 // instructions. 1432 Base = N; 1433 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1434 1435 if (N.getOpcode() != ISD::ADD || !CurDAG->isBaseWithConstantOffset(N)) 1436 return true; 1437 1438 ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1)); 1439 if (!RHS) 1440 return true; 1441 1442 uint32_t RHSC = (int)RHS->getZExtValue(); 1443 if (RHSC > 1020 || RHSC % 4 != 0) 1444 return true; 1445 1446 Base = N.getOperand(0); 1447 if (Base.getOpcode() == ISD::FrameIndex) { 1448 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1449 Base = CurDAG->getTargetFrameIndex( 1450 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1451 } 1452 1453 OffImm = CurDAG->getTargetConstant(RHSC/4, SDLoc(N), MVT::i32); 1454 return true; 1455 } 1456 1457 //===--------------------------------------------------------------------===// 1458 1459 /// getAL - Returns a ARMCC::AL immediate node. 1460 static inline SDValue getAL(SelectionDAG *CurDAG, const SDLoc &dl) { 1461 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, dl, MVT::i32); 1462 } 1463 1464 void ARMDAGToDAGISel::transferMemOperands(SDNode *N, SDNode *Result) { 1465 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand(); 1466 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Result), {MemOp}); 1467 } 1468 1469 bool ARMDAGToDAGISel::tryARMIndexedLoad(SDNode *N) { 1470 LoadSDNode *LD = cast<LoadSDNode>(N); 1471 ISD::MemIndexedMode AM = LD->getAddressingMode(); 1472 if (AM == ISD::UNINDEXED) 1473 return false; 1474 1475 EVT LoadedVT = LD->getMemoryVT(); 1476 SDValue Offset, AMOpc; 1477 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 1478 unsigned Opcode = 0; 1479 bool Match = false; 1480 if (LoadedVT == MVT::i32 && isPre && 1481 SelectAddrMode2OffsetImmPre(N, LD->getOffset(), Offset, AMOpc)) { 1482 Opcode = ARM::LDR_PRE_IMM; 1483 Match = true; 1484 } else if (LoadedVT == MVT::i32 && !isPre && 1485 SelectAddrMode2OffsetImm(N, LD->getOffset(), Offset, AMOpc)) { 1486 Opcode = ARM::LDR_POST_IMM; 1487 Match = true; 1488 } else if (LoadedVT == MVT::i32 && 1489 SelectAddrMode2OffsetReg(N, LD->getOffset(), Offset, AMOpc)) { 1490 Opcode = isPre ? ARM::LDR_PRE_REG : ARM::LDR_POST_REG; 1491 Match = true; 1492 1493 } else if (LoadedVT == MVT::i16 && 1494 SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 1495 Match = true; 1496 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) 1497 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) 1498 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); 1499 } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) { 1500 if (LD->getExtensionType() == ISD::SEXTLOAD) { 1501 if (SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 1502 Match = true; 1503 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; 1504 } 1505 } else { 1506 if (isPre && 1507 SelectAddrMode2OffsetImmPre(N, LD->getOffset(), Offset, AMOpc)) { 1508 Match = true; 1509 Opcode = ARM::LDRB_PRE_IMM; 1510 } else if (!isPre && 1511 SelectAddrMode2OffsetImm(N, LD->getOffset(), Offset, AMOpc)) { 1512 Match = true; 1513 Opcode = ARM::LDRB_POST_IMM; 1514 } else if (SelectAddrMode2OffsetReg(N, LD->getOffset(), Offset, AMOpc)) { 1515 Match = true; 1516 Opcode = isPre ? ARM::LDRB_PRE_REG : ARM::LDRB_POST_REG; 1517 } 1518 } 1519 } 1520 1521 if (Match) { 1522 if (Opcode == ARM::LDR_PRE_IMM || Opcode == ARM::LDRB_PRE_IMM) { 1523 SDValue Chain = LD->getChain(); 1524 SDValue Base = LD->getBasePtr(); 1525 SDValue Ops[]= { Base, AMOpc, getAL(CurDAG, SDLoc(N)), 1526 CurDAG->getRegister(0, MVT::i32), Chain }; 1527 SDNode *New = CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i32, MVT::i32, 1528 MVT::Other, Ops); 1529 transferMemOperands(N, New); 1530 ReplaceNode(N, New); 1531 return true; 1532 } else { 1533 SDValue Chain = LD->getChain(); 1534 SDValue Base = LD->getBasePtr(); 1535 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG, SDLoc(N)), 1536 CurDAG->getRegister(0, MVT::i32), Chain }; 1537 SDNode *New = CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i32, MVT::i32, 1538 MVT::Other, Ops); 1539 transferMemOperands(N, New); 1540 ReplaceNode(N, New); 1541 return true; 1542 } 1543 } 1544 1545 return false; 1546 } 1547 1548 bool ARMDAGToDAGISel::tryT1IndexedLoad(SDNode *N) { 1549 LoadSDNode *LD = cast<LoadSDNode>(N); 1550 EVT LoadedVT = LD->getMemoryVT(); 1551 ISD::MemIndexedMode AM = LD->getAddressingMode(); 1552 if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD || 1553 LoadedVT.getSimpleVT().SimpleTy != MVT::i32) 1554 return false; 1555 1556 auto *COffs = dyn_cast<ConstantSDNode>(LD->getOffset()); 1557 if (!COffs || COffs->getZExtValue() != 4) 1558 return false; 1559 1560 // A T1 post-indexed load is just a single register LDM: LDM r0!, {r1}. 1561 // The encoding of LDM is not how the rest of ISel expects a post-inc load to 1562 // look however, so we use a pseudo here and switch it for a tLDMIA_UPD after 1563 // ISel. 1564 SDValue Chain = LD->getChain(); 1565 SDValue Base = LD->getBasePtr(); 1566 SDValue Ops[]= { Base, getAL(CurDAG, SDLoc(N)), 1567 CurDAG->getRegister(0, MVT::i32), Chain }; 1568 SDNode *New = CurDAG->getMachineNode(ARM::tLDR_postidx, SDLoc(N), MVT::i32, 1569 MVT::i32, MVT::Other, Ops); 1570 transferMemOperands(N, New); 1571 ReplaceNode(N, New); 1572 return true; 1573 } 1574 1575 bool ARMDAGToDAGISel::tryT2IndexedLoad(SDNode *N) { 1576 LoadSDNode *LD = cast<LoadSDNode>(N); 1577 ISD::MemIndexedMode AM = LD->getAddressingMode(); 1578 if (AM == ISD::UNINDEXED) 1579 return false; 1580 1581 EVT LoadedVT = LD->getMemoryVT(); 1582 bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD; 1583 SDValue Offset; 1584 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 1585 unsigned Opcode = 0; 1586 bool Match = false; 1587 if (SelectT2AddrModeImm8Offset(N, LD->getOffset(), Offset)) { 1588 switch (LoadedVT.getSimpleVT().SimpleTy) { 1589 case MVT::i32: 1590 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST; 1591 break; 1592 case MVT::i16: 1593 if (isSExtLd) 1594 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST; 1595 else 1596 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST; 1597 break; 1598 case MVT::i8: 1599 case MVT::i1: 1600 if (isSExtLd) 1601 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST; 1602 else 1603 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST; 1604 break; 1605 default: 1606 return false; 1607 } 1608 Match = true; 1609 } 1610 1611 if (Match) { 1612 SDValue Chain = LD->getChain(); 1613 SDValue Base = LD->getBasePtr(); 1614 SDValue Ops[]= { Base, Offset, getAL(CurDAG, SDLoc(N)), 1615 CurDAG->getRegister(0, MVT::i32), Chain }; 1616 SDNode *New = CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i32, MVT::i32, 1617 MVT::Other, Ops); 1618 transferMemOperands(N, New); 1619 ReplaceNode(N, New); 1620 return true; 1621 } 1622 1623 return false; 1624 } 1625 1626 bool ARMDAGToDAGISel::tryMVEIndexedLoad(SDNode *N) { 1627 LoadSDNode *LD = cast<LoadSDNode>(N); 1628 ISD::MemIndexedMode AM = LD->getAddressingMode(); 1629 if (AM == ISD::UNINDEXED) 1630 return false; 1631 EVT LoadedVT = LD->getMemoryVT(); 1632 if (!LoadedVT.isVector()) 1633 return false; 1634 bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD; 1635 SDValue Offset; 1636 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 1637 unsigned Opcode = 0; 1638 unsigned Align = LD->getAlignment(); 1639 bool IsLE = Subtarget->isLittle(); 1640 1641 if (Align >= 2 && LoadedVT == MVT::v4i16 && 1642 SelectT2AddrModeImm7Offset(N, LD->getOffset(), Offset, 1)) { 1643 if (isSExtLd) 1644 Opcode = isPre ? ARM::MVE_VLDRHS32_pre : ARM::MVE_VLDRHS32_post; 1645 else 1646 Opcode = isPre ? ARM::MVE_VLDRHU32_pre : ARM::MVE_VLDRHU32_post; 1647 } else if (LoadedVT == MVT::v8i8 && 1648 SelectT2AddrModeImm7Offset(N, LD->getOffset(), Offset, 0)) { 1649 if (isSExtLd) 1650 Opcode = isPre ? ARM::MVE_VLDRBS16_pre : ARM::MVE_VLDRBS16_post; 1651 else 1652 Opcode = isPre ? ARM::MVE_VLDRBU16_pre : ARM::MVE_VLDRBU16_post; 1653 } else if (LoadedVT == MVT::v4i8 && 1654 SelectT2AddrModeImm7Offset(N, LD->getOffset(), Offset, 0)) { 1655 if (isSExtLd) 1656 Opcode = isPre ? ARM::MVE_VLDRBS32_pre : ARM::MVE_VLDRBS32_post; 1657 else 1658 Opcode = isPre ? ARM::MVE_VLDRBU32_pre : ARM::MVE_VLDRBU32_post; 1659 } else if (Align >= 4 && 1660 (IsLE || LoadedVT == MVT::v4i32 || LoadedVT == MVT::v4f32) && 1661 SelectT2AddrModeImm7Offset(N, LD->getOffset(), Offset, 2)) 1662 Opcode = isPre ? ARM::MVE_VLDRWU32_pre : ARM::MVE_VLDRWU32_post; 1663 else if (Align >= 2 && 1664 (IsLE || LoadedVT == MVT::v8i16 || LoadedVT == MVT::v8f16) && 1665 SelectT2AddrModeImm7Offset(N, LD->getOffset(), Offset, 1)) 1666 Opcode = isPre ? ARM::MVE_VLDRHU16_pre : ARM::MVE_VLDRHU16_post; 1667 else if ((IsLE || LoadedVT == MVT::v16i8) && 1668 SelectT2AddrModeImm7Offset(N, LD->getOffset(), Offset, 0)) 1669 Opcode = isPre ? ARM::MVE_VLDRBU8_pre : ARM::MVE_VLDRBU8_post; 1670 else 1671 return false; 1672 1673 SDValue Chain = LD->getChain(); 1674 SDValue Base = LD->getBasePtr(); 1675 SDValue Ops[] = {Base, Offset, 1676 CurDAG->getTargetConstant(ARMVCC::None, SDLoc(N), MVT::i32), 1677 CurDAG->getRegister(0, MVT::i32), Chain}; 1678 SDNode *New = CurDAG->getMachineNode(Opcode, SDLoc(N), LD->getValueType(0), 1679 MVT::i32, MVT::Other, Ops); 1680 transferMemOperands(N, New); 1681 ReplaceUses(SDValue(N, 0), SDValue(New, 1)); 1682 ReplaceUses(SDValue(N, 1), SDValue(New, 0)); 1683 ReplaceUses(SDValue(N, 2), SDValue(New, 2)); 1684 CurDAG->RemoveDeadNode(N); 1685 return true; 1686 } 1687 1688 /// Form a GPRPair pseudo register from a pair of GPR regs. 1689 SDNode *ARMDAGToDAGISel::createGPRPairNode(EVT VT, SDValue V0, SDValue V1) { 1690 SDLoc dl(V0.getNode()); 1691 SDValue RegClass = 1692 CurDAG->getTargetConstant(ARM::GPRPairRegClassID, dl, MVT::i32); 1693 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::gsub_0, dl, MVT::i32); 1694 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::gsub_1, dl, MVT::i32); 1695 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 }; 1696 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1697 } 1698 1699 /// Form a D register from a pair of S registers. 1700 SDNode *ARMDAGToDAGISel::createSRegPairNode(EVT VT, SDValue V0, SDValue V1) { 1701 SDLoc dl(V0.getNode()); 1702 SDValue RegClass = 1703 CurDAG->getTargetConstant(ARM::DPR_VFP2RegClassID, dl, MVT::i32); 1704 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, dl, MVT::i32); 1705 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, dl, MVT::i32); 1706 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 }; 1707 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1708 } 1709 1710 /// Form a quad register from a pair of D registers. 1711 SDNode *ARMDAGToDAGISel::createDRegPairNode(EVT VT, SDValue V0, SDValue V1) { 1712 SDLoc dl(V0.getNode()); 1713 SDValue RegClass = CurDAG->getTargetConstant(ARM::QPRRegClassID, dl, 1714 MVT::i32); 1715 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, dl, MVT::i32); 1716 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, dl, MVT::i32); 1717 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 }; 1718 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1719 } 1720 1721 /// Form 4 consecutive D registers from a pair of Q registers. 1722 SDNode *ARMDAGToDAGISel::createQRegPairNode(EVT VT, SDValue V0, SDValue V1) { 1723 SDLoc dl(V0.getNode()); 1724 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, dl, 1725 MVT::i32); 1726 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, dl, MVT::i32); 1727 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, dl, MVT::i32); 1728 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 }; 1729 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1730 } 1731 1732 /// Form 4 consecutive S registers. 1733 SDNode *ARMDAGToDAGISel::createQuadSRegsNode(EVT VT, SDValue V0, SDValue V1, 1734 SDValue V2, SDValue V3) { 1735 SDLoc dl(V0.getNode()); 1736 SDValue RegClass = 1737 CurDAG->getTargetConstant(ARM::QPR_VFP2RegClassID, dl, MVT::i32); 1738 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, dl, MVT::i32); 1739 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, dl, MVT::i32); 1740 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, dl, MVT::i32); 1741 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, dl, MVT::i32); 1742 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1, 1743 V2, SubReg2, V3, SubReg3 }; 1744 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1745 } 1746 1747 /// Form 4 consecutive D registers. 1748 SDNode *ARMDAGToDAGISel::createQuadDRegsNode(EVT VT, SDValue V0, SDValue V1, 1749 SDValue V2, SDValue V3) { 1750 SDLoc dl(V0.getNode()); 1751 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, dl, 1752 MVT::i32); 1753 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, dl, MVT::i32); 1754 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, dl, MVT::i32); 1755 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, dl, MVT::i32); 1756 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, dl, MVT::i32); 1757 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1, 1758 V2, SubReg2, V3, SubReg3 }; 1759 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1760 } 1761 1762 /// Form 4 consecutive Q registers. 1763 SDNode *ARMDAGToDAGISel::createQuadQRegsNode(EVT VT, SDValue V0, SDValue V1, 1764 SDValue V2, SDValue V3) { 1765 SDLoc dl(V0.getNode()); 1766 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQQQPRRegClassID, dl, 1767 MVT::i32); 1768 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, dl, MVT::i32); 1769 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, dl, MVT::i32); 1770 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, dl, MVT::i32); 1771 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, dl, MVT::i32); 1772 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1, 1773 V2, SubReg2, V3, SubReg3 }; 1774 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1775 } 1776 1777 /// GetVLDSTAlign - Get the alignment (in bytes) for the alignment operand 1778 /// of a NEON VLD or VST instruction. The supported values depend on the 1779 /// number of registers being loaded. 1780 SDValue ARMDAGToDAGISel::GetVLDSTAlign(SDValue Align, const SDLoc &dl, 1781 unsigned NumVecs, bool is64BitVector) { 1782 unsigned NumRegs = NumVecs; 1783 if (!is64BitVector && NumVecs < 3) 1784 NumRegs *= 2; 1785 1786 unsigned Alignment = cast<ConstantSDNode>(Align)->getZExtValue(); 1787 if (Alignment >= 32 && NumRegs == 4) 1788 Alignment = 32; 1789 else if (Alignment >= 16 && (NumRegs == 2 || NumRegs == 4)) 1790 Alignment = 16; 1791 else if (Alignment >= 8) 1792 Alignment = 8; 1793 else 1794 Alignment = 0; 1795 1796 return CurDAG->getTargetConstant(Alignment, dl, MVT::i32); 1797 } 1798 1799 static bool isVLDfixed(unsigned Opc) 1800 { 1801 switch (Opc) { 1802 default: return false; 1803 case ARM::VLD1d8wb_fixed : return true; 1804 case ARM::VLD1d16wb_fixed : return true; 1805 case ARM::VLD1d64Qwb_fixed : return true; 1806 case ARM::VLD1d32wb_fixed : return true; 1807 case ARM::VLD1d64wb_fixed : return true; 1808 case ARM::VLD1d64TPseudoWB_fixed : return true; 1809 case ARM::VLD1d64QPseudoWB_fixed : return true; 1810 case ARM::VLD1q8wb_fixed : return true; 1811 case ARM::VLD1q16wb_fixed : return true; 1812 case ARM::VLD1q32wb_fixed : return true; 1813 case ARM::VLD1q64wb_fixed : return true; 1814 case ARM::VLD1DUPd8wb_fixed : return true; 1815 case ARM::VLD1DUPd16wb_fixed : return true; 1816 case ARM::VLD1DUPd32wb_fixed : return true; 1817 case ARM::VLD1DUPq8wb_fixed : return true; 1818 case ARM::VLD1DUPq16wb_fixed : return true; 1819 case ARM::VLD1DUPq32wb_fixed : return true; 1820 case ARM::VLD2d8wb_fixed : return true; 1821 case ARM::VLD2d16wb_fixed : return true; 1822 case ARM::VLD2d32wb_fixed : return true; 1823 case ARM::VLD2q8PseudoWB_fixed : return true; 1824 case ARM::VLD2q16PseudoWB_fixed : return true; 1825 case ARM::VLD2q32PseudoWB_fixed : return true; 1826 case ARM::VLD2DUPd8wb_fixed : return true; 1827 case ARM::VLD2DUPd16wb_fixed : return true; 1828 case ARM::VLD2DUPd32wb_fixed : return true; 1829 } 1830 } 1831 1832 static bool isVSTfixed(unsigned Opc) 1833 { 1834 switch (Opc) { 1835 default: return false; 1836 case ARM::VST1d8wb_fixed : return true; 1837 case ARM::VST1d16wb_fixed : return true; 1838 case ARM::VST1d32wb_fixed : return true; 1839 case ARM::VST1d64wb_fixed : return true; 1840 case ARM::VST1q8wb_fixed : return true; 1841 case ARM::VST1q16wb_fixed : return true; 1842 case ARM::VST1q32wb_fixed : return true; 1843 case ARM::VST1q64wb_fixed : return true; 1844 case ARM::VST1d64TPseudoWB_fixed : return true; 1845 case ARM::VST1d64QPseudoWB_fixed : return true; 1846 case ARM::VST2d8wb_fixed : return true; 1847 case ARM::VST2d16wb_fixed : return true; 1848 case ARM::VST2d32wb_fixed : return true; 1849 case ARM::VST2q8PseudoWB_fixed : return true; 1850 case ARM::VST2q16PseudoWB_fixed : return true; 1851 case ARM::VST2q32PseudoWB_fixed : return true; 1852 } 1853 } 1854 1855 // Get the register stride update opcode of a VLD/VST instruction that 1856 // is otherwise equivalent to the given fixed stride updating instruction. 1857 static unsigned getVLDSTRegisterUpdateOpcode(unsigned Opc) { 1858 assert((isVLDfixed(Opc) || isVSTfixed(Opc)) 1859 && "Incorrect fixed stride updating instruction."); 1860 switch (Opc) { 1861 default: break; 1862 case ARM::VLD1d8wb_fixed: return ARM::VLD1d8wb_register; 1863 case ARM::VLD1d16wb_fixed: return ARM::VLD1d16wb_register; 1864 case ARM::VLD1d32wb_fixed: return ARM::VLD1d32wb_register; 1865 case ARM::VLD1d64wb_fixed: return ARM::VLD1d64wb_register; 1866 case ARM::VLD1q8wb_fixed: return ARM::VLD1q8wb_register; 1867 case ARM::VLD1q16wb_fixed: return ARM::VLD1q16wb_register; 1868 case ARM::VLD1q32wb_fixed: return ARM::VLD1q32wb_register; 1869 case ARM::VLD1q64wb_fixed: return ARM::VLD1q64wb_register; 1870 case ARM::VLD1d64Twb_fixed: return ARM::VLD1d64Twb_register; 1871 case ARM::VLD1d64Qwb_fixed: return ARM::VLD1d64Qwb_register; 1872 case ARM::VLD1d64TPseudoWB_fixed: return ARM::VLD1d64TPseudoWB_register; 1873 case ARM::VLD1d64QPseudoWB_fixed: return ARM::VLD1d64QPseudoWB_register; 1874 case ARM::VLD1DUPd8wb_fixed : return ARM::VLD1DUPd8wb_register; 1875 case ARM::VLD1DUPd16wb_fixed : return ARM::VLD1DUPd16wb_register; 1876 case ARM::VLD1DUPd32wb_fixed : return ARM::VLD1DUPd32wb_register; 1877 case ARM::VLD1DUPq8wb_fixed : return ARM::VLD1DUPq8wb_register; 1878 case ARM::VLD1DUPq16wb_fixed : return ARM::VLD1DUPq16wb_register; 1879 case ARM::VLD1DUPq32wb_fixed : return ARM::VLD1DUPq32wb_register; 1880 1881 case ARM::VST1d8wb_fixed: return ARM::VST1d8wb_register; 1882 case ARM::VST1d16wb_fixed: return ARM::VST1d16wb_register; 1883 case ARM::VST1d32wb_fixed: return ARM::VST1d32wb_register; 1884 case ARM::VST1d64wb_fixed: return ARM::VST1d64wb_register; 1885 case ARM::VST1q8wb_fixed: return ARM::VST1q8wb_register; 1886 case ARM::VST1q16wb_fixed: return ARM::VST1q16wb_register; 1887 case ARM::VST1q32wb_fixed: return ARM::VST1q32wb_register; 1888 case ARM::VST1q64wb_fixed: return ARM::VST1q64wb_register; 1889 case ARM::VST1d64TPseudoWB_fixed: return ARM::VST1d64TPseudoWB_register; 1890 case ARM::VST1d64QPseudoWB_fixed: return ARM::VST1d64QPseudoWB_register; 1891 1892 case ARM::VLD2d8wb_fixed: return ARM::VLD2d8wb_register; 1893 case ARM::VLD2d16wb_fixed: return ARM::VLD2d16wb_register; 1894 case ARM::VLD2d32wb_fixed: return ARM::VLD2d32wb_register; 1895 case ARM::VLD2q8PseudoWB_fixed: return ARM::VLD2q8PseudoWB_register; 1896 case ARM::VLD2q16PseudoWB_fixed: return ARM::VLD2q16PseudoWB_register; 1897 case ARM::VLD2q32PseudoWB_fixed: return ARM::VLD2q32PseudoWB_register; 1898 1899 case ARM::VST2d8wb_fixed: return ARM::VST2d8wb_register; 1900 case ARM::VST2d16wb_fixed: return ARM::VST2d16wb_register; 1901 case ARM::VST2d32wb_fixed: return ARM::VST2d32wb_register; 1902 case ARM::VST2q8PseudoWB_fixed: return ARM::VST2q8PseudoWB_register; 1903 case ARM::VST2q16PseudoWB_fixed: return ARM::VST2q16PseudoWB_register; 1904 case ARM::VST2q32PseudoWB_fixed: return ARM::VST2q32PseudoWB_register; 1905 1906 case ARM::VLD2DUPd8wb_fixed: return ARM::VLD2DUPd8wb_register; 1907 case ARM::VLD2DUPd16wb_fixed: return ARM::VLD2DUPd16wb_register; 1908 case ARM::VLD2DUPd32wb_fixed: return ARM::VLD2DUPd32wb_register; 1909 } 1910 return Opc; // If not one we handle, return it unchanged. 1911 } 1912 1913 /// Returns true if the given increment is a Constant known to be equal to the 1914 /// access size performed by a NEON load/store. This means the "[rN]!" form can 1915 /// be used. 1916 static bool isPerfectIncrement(SDValue Inc, EVT VecTy, unsigned NumVecs) { 1917 auto C = dyn_cast<ConstantSDNode>(Inc); 1918 return C && C->getZExtValue() == VecTy.getSizeInBits() / 8 * NumVecs; 1919 } 1920 1921 void ARMDAGToDAGISel::SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs, 1922 const uint16_t *DOpcodes, 1923 const uint16_t *QOpcodes0, 1924 const uint16_t *QOpcodes1) { 1925 assert(NumVecs >= 1 && NumVecs <= 4 && "VLD NumVecs out-of-range"); 1926 SDLoc dl(N); 1927 1928 SDValue MemAddr, Align; 1929 bool IsIntrinsic = !isUpdating; // By coincidence, all supported updating 1930 // nodes are not intrinsics. 1931 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1; 1932 if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align)) 1933 return; 1934 1935 SDValue Chain = N->getOperand(0); 1936 EVT VT = N->getValueType(0); 1937 bool is64BitVector = VT.is64BitVector(); 1938 Align = GetVLDSTAlign(Align, dl, NumVecs, is64BitVector); 1939 1940 unsigned OpcodeIndex; 1941 switch (VT.getSimpleVT().SimpleTy) { 1942 default: llvm_unreachable("unhandled vld type"); 1943 // Double-register operations: 1944 case MVT::v8i8: OpcodeIndex = 0; break; 1945 case MVT::v4f16: 1946 case MVT::v4i16: OpcodeIndex = 1; break; 1947 case MVT::v2f32: 1948 case MVT::v2i32: OpcodeIndex = 2; break; 1949 case MVT::v1i64: OpcodeIndex = 3; break; 1950 // Quad-register operations: 1951 case MVT::v16i8: OpcodeIndex = 0; break; 1952 case MVT::v8f16: 1953 case MVT::v8i16: OpcodeIndex = 1; break; 1954 case MVT::v4f32: 1955 case MVT::v4i32: OpcodeIndex = 2; break; 1956 case MVT::v2f64: 1957 case MVT::v2i64: OpcodeIndex = 3; break; 1958 } 1959 1960 EVT ResTy; 1961 if (NumVecs == 1) 1962 ResTy = VT; 1963 else { 1964 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs; 1965 if (!is64BitVector) 1966 ResTyElts *= 2; 1967 ResTy = EVT::getVectorVT(*CurDAG->getContext(), MVT::i64, ResTyElts); 1968 } 1969 std::vector<EVT> ResTys; 1970 ResTys.push_back(ResTy); 1971 if (isUpdating) 1972 ResTys.push_back(MVT::i32); 1973 ResTys.push_back(MVT::Other); 1974 1975 SDValue Pred = getAL(CurDAG, dl); 1976 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1977 SDNode *VLd; 1978 SmallVector<SDValue, 7> Ops; 1979 1980 // Double registers and VLD1/VLD2 quad registers are directly supported. 1981 if (is64BitVector || NumVecs <= 2) { 1982 unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] : 1983 QOpcodes0[OpcodeIndex]); 1984 Ops.push_back(MemAddr); 1985 Ops.push_back(Align); 1986 if (isUpdating) { 1987 SDValue Inc = N->getOperand(AddrOpIdx + 1); 1988 bool IsImmUpdate = isPerfectIncrement(Inc, VT, NumVecs); 1989 if (!IsImmUpdate) { 1990 // We use a VLD1 for v1i64 even if the pseudo says vld2/3/4, so 1991 // check for the opcode rather than the number of vector elements. 1992 if (isVLDfixed(Opc)) 1993 Opc = getVLDSTRegisterUpdateOpcode(Opc); 1994 Ops.push_back(Inc); 1995 // VLD1/VLD2 fixed increment does not need Reg0 so only include it in 1996 // the operands if not such an opcode. 1997 } else if (!isVLDfixed(Opc)) 1998 Ops.push_back(Reg0); 1999 } 2000 Ops.push_back(Pred); 2001 Ops.push_back(Reg0); 2002 Ops.push_back(Chain); 2003 VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 2004 2005 } else { 2006 // Otherwise, quad registers are loaded with two separate instructions, 2007 // where one loads the even registers and the other loads the odd registers. 2008 EVT AddrTy = MemAddr.getValueType(); 2009 2010 // Load the even subregs. This is always an updating load, so that it 2011 // provides the address to the second load for the odd subregs. 2012 SDValue ImplDef = 2013 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy), 0); 2014 const SDValue OpsA[] = { MemAddr, Align, Reg0, ImplDef, Pred, Reg0, Chain }; 2015 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl, 2016 ResTy, AddrTy, MVT::Other, OpsA); 2017 Chain = SDValue(VLdA, 2); 2018 2019 // Load the odd subregs. 2020 Ops.push_back(SDValue(VLdA, 1)); 2021 Ops.push_back(Align); 2022 if (isUpdating) { 2023 SDValue Inc = N->getOperand(AddrOpIdx + 1); 2024 assert(isa<ConstantSDNode>(Inc.getNode()) && 2025 "only constant post-increment update allowed for VLD3/4"); 2026 (void)Inc; 2027 Ops.push_back(Reg0); 2028 } 2029 Ops.push_back(SDValue(VLdA, 0)); 2030 Ops.push_back(Pred); 2031 Ops.push_back(Reg0); 2032 Ops.push_back(Chain); 2033 VLd = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, Ops); 2034 } 2035 2036 // Transfer memoperands. 2037 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 2038 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VLd), {MemOp}); 2039 2040 if (NumVecs == 1) { 2041 ReplaceNode(N, VLd); 2042 return; 2043 } 2044 2045 // Extract out the subregisters. 2046 SDValue SuperReg = SDValue(VLd, 0); 2047 static_assert(ARM::dsub_7 == ARM::dsub_0 + 7 && 2048 ARM::qsub_3 == ARM::qsub_0 + 3, 2049 "Unexpected subreg numbering"); 2050 unsigned Sub0 = (is64BitVector ? ARM::dsub_0 : ARM::qsub_0); 2051 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 2052 ReplaceUses(SDValue(N, Vec), 2053 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg)); 2054 ReplaceUses(SDValue(N, NumVecs), SDValue(VLd, 1)); 2055 if (isUpdating) 2056 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(VLd, 2)); 2057 CurDAG->RemoveDeadNode(N); 2058 } 2059 2060 void ARMDAGToDAGISel::SelectVST(SDNode *N, bool isUpdating, unsigned NumVecs, 2061 const uint16_t *DOpcodes, 2062 const uint16_t *QOpcodes0, 2063 const uint16_t *QOpcodes1) { 2064 assert(NumVecs >= 1 && NumVecs <= 4 && "VST NumVecs out-of-range"); 2065 SDLoc dl(N); 2066 2067 SDValue MemAddr, Align; 2068 bool IsIntrinsic = !isUpdating; // By coincidence, all supported updating 2069 // nodes are not intrinsics. 2070 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1; 2071 unsigned Vec0Idx = 3; // AddrOpIdx + (isUpdating ? 2 : 1) 2072 if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align)) 2073 return; 2074 2075 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 2076 2077 SDValue Chain = N->getOperand(0); 2078 EVT VT = N->getOperand(Vec0Idx).getValueType(); 2079 bool is64BitVector = VT.is64BitVector(); 2080 Align = GetVLDSTAlign(Align, dl, NumVecs, is64BitVector); 2081 2082 unsigned OpcodeIndex; 2083 switch (VT.getSimpleVT().SimpleTy) { 2084 default: llvm_unreachable("unhandled vst type"); 2085 // Double-register operations: 2086 case MVT::v8i8: OpcodeIndex = 0; break; 2087 case MVT::v4f16: 2088 case MVT::v4i16: OpcodeIndex = 1; break; 2089 case MVT::v2f32: 2090 case MVT::v2i32: OpcodeIndex = 2; break; 2091 case MVT::v1i64: OpcodeIndex = 3; break; 2092 // Quad-register operations: 2093 case MVT::v16i8: OpcodeIndex = 0; break; 2094 case MVT::v8f16: 2095 case MVT::v8i16: OpcodeIndex = 1; break; 2096 case MVT::v4f32: 2097 case MVT::v4i32: OpcodeIndex = 2; break; 2098 case MVT::v2f64: 2099 case MVT::v2i64: OpcodeIndex = 3; break; 2100 } 2101 2102 std::vector<EVT> ResTys; 2103 if (isUpdating) 2104 ResTys.push_back(MVT::i32); 2105 ResTys.push_back(MVT::Other); 2106 2107 SDValue Pred = getAL(CurDAG, dl); 2108 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2109 SmallVector<SDValue, 7> Ops; 2110 2111 // Double registers and VST1/VST2 quad registers are directly supported. 2112 if (is64BitVector || NumVecs <= 2) { 2113 SDValue SrcReg; 2114 if (NumVecs == 1) { 2115 SrcReg = N->getOperand(Vec0Idx); 2116 } else if (is64BitVector) { 2117 // Form a REG_SEQUENCE to force register allocation. 2118 SDValue V0 = N->getOperand(Vec0Idx + 0); 2119 SDValue V1 = N->getOperand(Vec0Idx + 1); 2120 if (NumVecs == 2) 2121 SrcReg = SDValue(createDRegPairNode(MVT::v2i64, V0, V1), 0); 2122 else { 2123 SDValue V2 = N->getOperand(Vec0Idx + 2); 2124 // If it's a vst3, form a quad D-register and leave the last part as 2125 // an undef. 2126 SDValue V3 = (NumVecs == 3) 2127 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0) 2128 : N->getOperand(Vec0Idx + 3); 2129 SrcReg = SDValue(createQuadDRegsNode(MVT::v4i64, V0, V1, V2, V3), 0); 2130 } 2131 } else { 2132 // Form a QQ register. 2133 SDValue Q0 = N->getOperand(Vec0Idx); 2134 SDValue Q1 = N->getOperand(Vec0Idx + 1); 2135 SrcReg = SDValue(createQRegPairNode(MVT::v4i64, Q0, Q1), 0); 2136 } 2137 2138 unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] : 2139 QOpcodes0[OpcodeIndex]); 2140 Ops.push_back(MemAddr); 2141 Ops.push_back(Align); 2142 if (isUpdating) { 2143 SDValue Inc = N->getOperand(AddrOpIdx + 1); 2144 bool IsImmUpdate = isPerfectIncrement(Inc, VT, NumVecs); 2145 if (!IsImmUpdate) { 2146 // We use a VST1 for v1i64 even if the pseudo says VST2/3/4, so 2147 // check for the opcode rather than the number of vector elements. 2148 if (isVSTfixed(Opc)) 2149 Opc = getVLDSTRegisterUpdateOpcode(Opc); 2150 Ops.push_back(Inc); 2151 } 2152 // VST1/VST2 fixed increment does not need Reg0 so only include it in 2153 // the operands if not such an opcode. 2154 else if (!isVSTfixed(Opc)) 2155 Ops.push_back(Reg0); 2156 } 2157 Ops.push_back(SrcReg); 2158 Ops.push_back(Pred); 2159 Ops.push_back(Reg0); 2160 Ops.push_back(Chain); 2161 SDNode *VSt = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 2162 2163 // Transfer memoperands. 2164 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VSt), {MemOp}); 2165 2166 ReplaceNode(N, VSt); 2167 return; 2168 } 2169 2170 // Otherwise, quad registers are stored with two separate instructions, 2171 // where one stores the even registers and the other stores the odd registers. 2172 2173 // Form the QQQQ REG_SEQUENCE. 2174 SDValue V0 = N->getOperand(Vec0Idx + 0); 2175 SDValue V1 = N->getOperand(Vec0Idx + 1); 2176 SDValue V2 = N->getOperand(Vec0Idx + 2); 2177 SDValue V3 = (NumVecs == 3) 2178 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0) 2179 : N->getOperand(Vec0Idx + 3); 2180 SDValue RegSeq = SDValue(createQuadQRegsNode(MVT::v8i64, V0, V1, V2, V3), 0); 2181 2182 // Store the even D registers. This is always an updating store, so that it 2183 // provides the address to the second store for the odd subregs. 2184 const SDValue OpsA[] = { MemAddr, Align, Reg0, RegSeq, Pred, Reg0, Chain }; 2185 SDNode *VStA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl, 2186 MemAddr.getValueType(), 2187 MVT::Other, OpsA); 2188 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VStA), {MemOp}); 2189 Chain = SDValue(VStA, 1); 2190 2191 // Store the odd D registers. 2192 Ops.push_back(SDValue(VStA, 0)); 2193 Ops.push_back(Align); 2194 if (isUpdating) { 2195 SDValue Inc = N->getOperand(AddrOpIdx + 1); 2196 assert(isa<ConstantSDNode>(Inc.getNode()) && 2197 "only constant post-increment update allowed for VST3/4"); 2198 (void)Inc; 2199 Ops.push_back(Reg0); 2200 } 2201 Ops.push_back(RegSeq); 2202 Ops.push_back(Pred); 2203 Ops.push_back(Reg0); 2204 Ops.push_back(Chain); 2205 SDNode *VStB = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, 2206 Ops); 2207 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VStB), {MemOp}); 2208 ReplaceNode(N, VStB); 2209 } 2210 2211 void ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad, bool isUpdating, 2212 unsigned NumVecs, 2213 const uint16_t *DOpcodes, 2214 const uint16_t *QOpcodes) { 2215 assert(NumVecs >=2 && NumVecs <= 4 && "VLDSTLane NumVecs out-of-range"); 2216 SDLoc dl(N); 2217 2218 SDValue MemAddr, Align; 2219 bool IsIntrinsic = !isUpdating; // By coincidence, all supported updating 2220 // nodes are not intrinsics. 2221 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1; 2222 unsigned Vec0Idx = 3; // AddrOpIdx + (isUpdating ? 2 : 1) 2223 if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align)) 2224 return; 2225 2226 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 2227 2228 SDValue Chain = N->getOperand(0); 2229 unsigned Lane = 2230 cast<ConstantSDNode>(N->getOperand(Vec0Idx + NumVecs))->getZExtValue(); 2231 EVT VT = N->getOperand(Vec0Idx).getValueType(); 2232 bool is64BitVector = VT.is64BitVector(); 2233 2234 unsigned Alignment = 0; 2235 if (NumVecs != 3) { 2236 Alignment = cast<ConstantSDNode>(Align)->getZExtValue(); 2237 unsigned NumBytes = NumVecs * VT.getScalarSizeInBits() / 8; 2238 if (Alignment > NumBytes) 2239 Alignment = NumBytes; 2240 if (Alignment < 8 && Alignment < NumBytes) 2241 Alignment = 0; 2242 // Alignment must be a power of two; make sure of that. 2243 Alignment = (Alignment & -Alignment); 2244 if (Alignment == 1) 2245 Alignment = 0; 2246 } 2247 Align = CurDAG->getTargetConstant(Alignment, dl, MVT::i32); 2248 2249 unsigned OpcodeIndex; 2250 switch (VT.getSimpleVT().SimpleTy) { 2251 default: llvm_unreachable("unhandled vld/vst lane type"); 2252 // Double-register operations: 2253 case MVT::v8i8: OpcodeIndex = 0; break; 2254 case MVT::v4f16: 2255 case MVT::v4i16: OpcodeIndex = 1; break; 2256 case MVT::v2f32: 2257 case MVT::v2i32: OpcodeIndex = 2; break; 2258 // Quad-register operations: 2259 case MVT::v8f16: 2260 case MVT::v8i16: OpcodeIndex = 0; break; 2261 case MVT::v4f32: 2262 case MVT::v4i32: OpcodeIndex = 1; break; 2263 } 2264 2265 std::vector<EVT> ResTys; 2266 if (IsLoad) { 2267 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs; 2268 if (!is64BitVector) 2269 ResTyElts *= 2; 2270 ResTys.push_back(EVT::getVectorVT(*CurDAG->getContext(), 2271 MVT::i64, ResTyElts)); 2272 } 2273 if (isUpdating) 2274 ResTys.push_back(MVT::i32); 2275 ResTys.push_back(MVT::Other); 2276 2277 SDValue Pred = getAL(CurDAG, dl); 2278 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2279 2280 SmallVector<SDValue, 8> Ops; 2281 Ops.push_back(MemAddr); 2282 Ops.push_back(Align); 2283 if (isUpdating) { 2284 SDValue Inc = N->getOperand(AddrOpIdx + 1); 2285 bool IsImmUpdate = 2286 isPerfectIncrement(Inc, VT.getVectorElementType(), NumVecs); 2287 Ops.push_back(IsImmUpdate ? Reg0 : Inc); 2288 } 2289 2290 SDValue SuperReg; 2291 SDValue V0 = N->getOperand(Vec0Idx + 0); 2292 SDValue V1 = N->getOperand(Vec0Idx + 1); 2293 if (NumVecs == 2) { 2294 if (is64BitVector) 2295 SuperReg = SDValue(createDRegPairNode(MVT::v2i64, V0, V1), 0); 2296 else 2297 SuperReg = SDValue(createQRegPairNode(MVT::v4i64, V0, V1), 0); 2298 } else { 2299 SDValue V2 = N->getOperand(Vec0Idx + 2); 2300 SDValue V3 = (NumVecs == 3) 2301 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0) 2302 : N->getOperand(Vec0Idx + 3); 2303 if (is64BitVector) 2304 SuperReg = SDValue(createQuadDRegsNode(MVT::v4i64, V0, V1, V2, V3), 0); 2305 else 2306 SuperReg = SDValue(createQuadQRegsNode(MVT::v8i64, V0, V1, V2, V3), 0); 2307 } 2308 Ops.push_back(SuperReg); 2309 Ops.push_back(getI32Imm(Lane, dl)); 2310 Ops.push_back(Pred); 2311 Ops.push_back(Reg0); 2312 Ops.push_back(Chain); 2313 2314 unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] : 2315 QOpcodes[OpcodeIndex]); 2316 SDNode *VLdLn = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 2317 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VLdLn), {MemOp}); 2318 if (!IsLoad) { 2319 ReplaceNode(N, VLdLn); 2320 return; 2321 } 2322 2323 // Extract the subregisters. 2324 SuperReg = SDValue(VLdLn, 0); 2325 static_assert(ARM::dsub_7 == ARM::dsub_0 + 7 && 2326 ARM::qsub_3 == ARM::qsub_0 + 3, 2327 "Unexpected subreg numbering"); 2328 unsigned Sub0 = is64BitVector ? ARM::dsub_0 : ARM::qsub_0; 2329 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 2330 ReplaceUses(SDValue(N, Vec), 2331 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg)); 2332 ReplaceUses(SDValue(N, NumVecs), SDValue(VLdLn, 1)); 2333 if (isUpdating) 2334 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(VLdLn, 2)); 2335 CurDAG->RemoveDeadNode(N); 2336 } 2337 2338 template <typename SDValueVector> 2339 void ARMDAGToDAGISel::AddMVEPredicateToOps(SDValueVector &Ops, SDLoc Loc, 2340 SDValue PredicateMask) { 2341 Ops.push_back(CurDAG->getTargetConstant(ARMVCC::Then, Loc, MVT::i32)); 2342 Ops.push_back(PredicateMask); 2343 } 2344 2345 template <typename SDValueVector> 2346 void ARMDAGToDAGISel::AddMVEPredicateToOps(SDValueVector &Ops, SDLoc Loc, 2347 SDValue PredicateMask, 2348 SDValue Inactive) { 2349 Ops.push_back(CurDAG->getTargetConstant(ARMVCC::Then, Loc, MVT::i32)); 2350 Ops.push_back(PredicateMask); 2351 Ops.push_back(Inactive); 2352 } 2353 2354 template <typename SDValueVector> 2355 void ARMDAGToDAGISel::AddEmptyMVEPredicateToOps(SDValueVector &Ops, SDLoc Loc) { 2356 Ops.push_back(CurDAG->getTargetConstant(ARMVCC::None, Loc, MVT::i32)); 2357 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 2358 } 2359 2360 template <typename SDValueVector> 2361 void ARMDAGToDAGISel::AddEmptyMVEPredicateToOps(SDValueVector &Ops, SDLoc Loc, 2362 EVT InactiveTy) { 2363 Ops.push_back(CurDAG->getTargetConstant(ARMVCC::None, Loc, MVT::i32)); 2364 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 2365 Ops.push_back(SDValue( 2366 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, Loc, InactiveTy), 0)); 2367 } 2368 2369 void ARMDAGToDAGISel::SelectMVE_WB(SDNode *N, const uint16_t *Opcodes, 2370 bool Predicated) { 2371 SDLoc Loc(N); 2372 SmallVector<SDValue, 8> Ops; 2373 2374 uint16_t Opcode; 2375 switch (N->getValueType(1).getVectorElementType().getSizeInBits()) { 2376 case 32: 2377 Opcode = Opcodes[0]; 2378 break; 2379 case 64: 2380 Opcode = Opcodes[1]; 2381 break; 2382 default: 2383 llvm_unreachable("bad vector element size in SelectMVE_WB"); 2384 } 2385 2386 Ops.push_back(N->getOperand(2)); // vector of base addresses 2387 2388 int32_t ImmValue = cast<ConstantSDNode>(N->getOperand(3))->getZExtValue(); 2389 Ops.push_back(getI32Imm(ImmValue, Loc)); // immediate offset 2390 2391 if (Predicated) 2392 AddMVEPredicateToOps(Ops, Loc, N->getOperand(4)); 2393 else 2394 AddEmptyMVEPredicateToOps(Ops, Loc); 2395 2396 Ops.push_back(N->getOperand(0)); // chain 2397 2398 CurDAG->SelectNodeTo(N, Opcode, N->getVTList(), makeArrayRef(Ops)); 2399 } 2400 2401 void ARMDAGToDAGISel::SelectMVE_LongShift(SDNode *N, uint16_t Opcode, 2402 bool Immediate) { 2403 SDLoc Loc(N); 2404 SmallVector<SDValue, 8> Ops; 2405 2406 // Two 32-bit halves of the value to be shifted 2407 Ops.push_back(N->getOperand(1)); 2408 Ops.push_back(N->getOperand(2)); 2409 2410 // The shift count 2411 if (Immediate) { 2412 int32_t ImmValue = cast<ConstantSDNode>(N->getOperand(3))->getZExtValue(); 2413 Ops.push_back(getI32Imm(ImmValue, Loc)); // immediate offset 2414 } else { 2415 Ops.push_back(N->getOperand(3)); 2416 } 2417 2418 // MVE scalar shifts are IT-predicable, so include the standard 2419 // predicate arguments. 2420 Ops.push_back(getAL(CurDAG, Loc)); 2421 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 2422 2423 CurDAG->SelectNodeTo(N, Opcode, N->getVTList(), makeArrayRef(Ops)); 2424 } 2425 2426 void ARMDAGToDAGISel::SelectMVE_VADCSBC(SDNode *N, uint16_t OpcodeWithCarry, 2427 uint16_t OpcodeWithNoCarry, 2428 bool Add, bool Predicated) { 2429 SDLoc Loc(N); 2430 SmallVector<SDValue, 8> Ops; 2431 uint16_t Opcode; 2432 2433 unsigned FirstInputOp = Predicated ? 2 : 1; 2434 2435 // Two input vectors and the input carry flag 2436 Ops.push_back(N->getOperand(FirstInputOp)); 2437 Ops.push_back(N->getOperand(FirstInputOp + 1)); 2438 SDValue CarryIn = N->getOperand(FirstInputOp + 2); 2439 ConstantSDNode *CarryInConstant = dyn_cast<ConstantSDNode>(CarryIn); 2440 uint32_t CarryMask = 1 << 29; 2441 uint32_t CarryExpected = Add ? 0 : CarryMask; 2442 if (CarryInConstant && 2443 (CarryInConstant->getZExtValue() & CarryMask) == CarryExpected) { 2444 Opcode = OpcodeWithNoCarry; 2445 } else { 2446 Ops.push_back(CarryIn); 2447 Opcode = OpcodeWithCarry; 2448 } 2449 2450 if (Predicated) 2451 AddMVEPredicateToOps(Ops, Loc, 2452 N->getOperand(FirstInputOp + 3), // predicate 2453 N->getOperand(FirstInputOp - 1)); // inactive 2454 else 2455 AddEmptyMVEPredicateToOps(Ops, Loc, N->getValueType(0)); 2456 2457 CurDAG->SelectNodeTo(N, Opcode, N->getVTList(), makeArrayRef(Ops)); 2458 } 2459 2460 void ARMDAGToDAGISel::SelectMVE_VLD(SDNode *N, unsigned NumVecs, 2461 const uint16_t *const *Opcodes) { 2462 EVT VT = N->getValueType(0); 2463 SDLoc Loc(N); 2464 2465 const uint16_t *OurOpcodes; 2466 switch (VT.getVectorElementType().getSizeInBits()) { 2467 case 8: 2468 OurOpcodes = Opcodes[0]; 2469 break; 2470 case 16: 2471 OurOpcodes = Opcodes[1]; 2472 break; 2473 case 32: 2474 OurOpcodes = Opcodes[2]; 2475 break; 2476 default: 2477 llvm_unreachable("bad vector element size in SelectMVE_VLD"); 2478 } 2479 2480 EVT DataTy = EVT::getVectorVT(*CurDAG->getContext(), MVT::i64, NumVecs * 2); 2481 EVT ResultTys[] = {DataTy, MVT::Other}; 2482 2483 auto Data = SDValue( 2484 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, Loc, DataTy), 0); 2485 SDValue Chain = N->getOperand(0); 2486 for (unsigned Stage = 0; Stage < NumVecs; ++Stage) { 2487 SDValue Ops[] = {Data, N->getOperand(2), Chain}; 2488 auto LoadInst = 2489 CurDAG->getMachineNode(OurOpcodes[Stage], Loc, ResultTys, Ops); 2490 Data = SDValue(LoadInst, 0); 2491 Chain = SDValue(LoadInst, 1); 2492 } 2493 2494 for (unsigned i = 0; i < NumVecs; i++) 2495 ReplaceUses(SDValue(N, i), 2496 CurDAG->getTargetExtractSubreg(ARM::qsub_0 + i, Loc, VT, Data)); 2497 ReplaceUses(SDValue(N, NumVecs), Chain); 2498 CurDAG->RemoveDeadNode(N); 2499 } 2500 2501 void ARMDAGToDAGISel::SelectVLDDup(SDNode *N, bool IsIntrinsic, 2502 bool isUpdating, unsigned NumVecs, 2503 const uint16_t *DOpcodes, 2504 const uint16_t *QOpcodes0, 2505 const uint16_t *QOpcodes1) { 2506 assert(NumVecs >= 1 && NumVecs <= 4 && "VLDDup NumVecs out-of-range"); 2507 SDLoc dl(N); 2508 2509 SDValue MemAddr, Align; 2510 unsigned AddrOpIdx = IsIntrinsic ? 2 : 1; 2511 if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align)) 2512 return; 2513 2514 SDValue Chain = N->getOperand(0); 2515 EVT VT = N->getValueType(0); 2516 bool is64BitVector = VT.is64BitVector(); 2517 2518 unsigned Alignment = 0; 2519 if (NumVecs != 3) { 2520 Alignment = cast<ConstantSDNode>(Align)->getZExtValue(); 2521 unsigned NumBytes = NumVecs * VT.getScalarSizeInBits() / 8; 2522 if (Alignment > NumBytes) 2523 Alignment = NumBytes; 2524 if (Alignment < 8 && Alignment < NumBytes) 2525 Alignment = 0; 2526 // Alignment must be a power of two; make sure of that. 2527 Alignment = (Alignment & -Alignment); 2528 if (Alignment == 1) 2529 Alignment = 0; 2530 } 2531 Align = CurDAG->getTargetConstant(Alignment, dl, MVT::i32); 2532 2533 unsigned OpcodeIndex; 2534 switch (VT.getSimpleVT().SimpleTy) { 2535 default: llvm_unreachable("unhandled vld-dup type"); 2536 case MVT::v8i8: 2537 case MVT::v16i8: OpcodeIndex = 0; break; 2538 case MVT::v4i16: 2539 case MVT::v8i16: 2540 case MVT::v4f16: 2541 case MVT::v8f16: 2542 OpcodeIndex = 1; break; 2543 case MVT::v2f32: 2544 case MVT::v2i32: 2545 case MVT::v4f32: 2546 case MVT::v4i32: OpcodeIndex = 2; break; 2547 case MVT::v1f64: 2548 case MVT::v1i64: OpcodeIndex = 3; break; 2549 } 2550 2551 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs; 2552 if (!is64BitVector) 2553 ResTyElts *= 2; 2554 EVT ResTy = EVT::getVectorVT(*CurDAG->getContext(), MVT::i64, ResTyElts); 2555 2556 std::vector<EVT> ResTys; 2557 ResTys.push_back(ResTy); 2558 if (isUpdating) 2559 ResTys.push_back(MVT::i32); 2560 ResTys.push_back(MVT::Other); 2561 2562 SDValue Pred = getAL(CurDAG, dl); 2563 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2564 2565 SDNode *VLdDup; 2566 if (is64BitVector || NumVecs == 1) { 2567 SmallVector<SDValue, 6> Ops; 2568 Ops.push_back(MemAddr); 2569 Ops.push_back(Align); 2570 unsigned Opc = is64BitVector ? DOpcodes[OpcodeIndex] : 2571 QOpcodes0[OpcodeIndex]; 2572 if (isUpdating) { 2573 // fixed-stride update instructions don't have an explicit writeback 2574 // operand. It's implicit in the opcode itself. 2575 SDValue Inc = N->getOperand(2); 2576 bool IsImmUpdate = 2577 isPerfectIncrement(Inc, VT.getVectorElementType(), NumVecs); 2578 if (NumVecs <= 2 && !IsImmUpdate) 2579 Opc = getVLDSTRegisterUpdateOpcode(Opc); 2580 if (!IsImmUpdate) 2581 Ops.push_back(Inc); 2582 // FIXME: VLD3 and VLD4 haven't been updated to that form yet. 2583 else if (NumVecs > 2) 2584 Ops.push_back(Reg0); 2585 } 2586 Ops.push_back(Pred); 2587 Ops.push_back(Reg0); 2588 Ops.push_back(Chain); 2589 VLdDup = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 2590 } else if (NumVecs == 2) { 2591 const SDValue OpsA[] = { MemAddr, Align, Pred, Reg0, Chain }; 2592 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], 2593 dl, ResTys, OpsA); 2594 2595 Chain = SDValue(VLdA, 1); 2596 const SDValue OpsB[] = { MemAddr, Align, Pred, Reg0, Chain }; 2597 VLdDup = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, OpsB); 2598 } else { 2599 SDValue ImplDef = 2600 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy), 0); 2601 const SDValue OpsA[] = { MemAddr, Align, ImplDef, Pred, Reg0, Chain }; 2602 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], 2603 dl, ResTys, OpsA); 2604 2605 SDValue SuperReg = SDValue(VLdA, 0); 2606 Chain = SDValue(VLdA, 1); 2607 const SDValue OpsB[] = { MemAddr, Align, SuperReg, Pred, Reg0, Chain }; 2608 VLdDup = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, OpsB); 2609 } 2610 2611 // Transfer memoperands. 2612 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 2613 CurDAG->setNodeMemRefs(cast<MachineSDNode>(VLdDup), {MemOp}); 2614 2615 // Extract the subregisters. 2616 if (NumVecs == 1) { 2617 ReplaceUses(SDValue(N, 0), SDValue(VLdDup, 0)); 2618 } else { 2619 SDValue SuperReg = SDValue(VLdDup, 0); 2620 static_assert(ARM::dsub_7 == ARM::dsub_0 + 7, "Unexpected subreg numbering"); 2621 unsigned SubIdx = is64BitVector ? ARM::dsub_0 : ARM::qsub_0; 2622 for (unsigned Vec = 0; Vec != NumVecs; ++Vec) { 2623 ReplaceUses(SDValue(N, Vec), 2624 CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, SuperReg)); 2625 } 2626 } 2627 ReplaceUses(SDValue(N, NumVecs), SDValue(VLdDup, 1)); 2628 if (isUpdating) 2629 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(VLdDup, 2)); 2630 CurDAG->RemoveDeadNode(N); 2631 } 2632 2633 bool ARMDAGToDAGISel::tryV6T2BitfieldExtractOp(SDNode *N, bool isSigned) { 2634 if (!Subtarget->hasV6T2Ops()) 2635 return false; 2636 2637 unsigned Opc = isSigned 2638 ? (Subtarget->isThumb() ? ARM::t2SBFX : ARM::SBFX) 2639 : (Subtarget->isThumb() ? ARM::t2UBFX : ARM::UBFX); 2640 SDLoc dl(N); 2641 2642 // For unsigned extracts, check for a shift right and mask 2643 unsigned And_imm = 0; 2644 if (N->getOpcode() == ISD::AND) { 2645 if (isOpcWithIntImmediate(N, ISD::AND, And_imm)) { 2646 2647 // The immediate is a mask of the low bits iff imm & (imm+1) == 0 2648 if (And_imm & (And_imm + 1)) 2649 return false; 2650 2651 unsigned Srl_imm = 0; 2652 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRL, 2653 Srl_imm)) { 2654 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 2655 2656 // Mask off the unnecessary bits of the AND immediate; normally 2657 // DAGCombine will do this, but that might not happen if 2658 // targetShrinkDemandedConstant chooses a different immediate. 2659 And_imm &= -1U >> Srl_imm; 2660 2661 // Note: The width operand is encoded as width-1. 2662 unsigned Width = countTrailingOnes(And_imm) - 1; 2663 unsigned LSB = Srl_imm; 2664 2665 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2666 2667 if ((LSB + Width + 1) == N->getValueType(0).getSizeInBits()) { 2668 // It's cheaper to use a right shift to extract the top bits. 2669 if (Subtarget->isThumb()) { 2670 Opc = isSigned ? ARM::t2ASRri : ARM::t2LSRri; 2671 SDValue Ops[] = { N->getOperand(0).getOperand(0), 2672 CurDAG->getTargetConstant(LSB, dl, MVT::i32), 2673 getAL(CurDAG, dl), Reg0, Reg0 }; 2674 CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2675 return true; 2676 } 2677 2678 // ARM models shift instructions as MOVsi with shifter operand. 2679 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(ISD::SRL); 2680 SDValue ShOpc = 2681 CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, LSB), dl, 2682 MVT::i32); 2683 SDValue Ops[] = { N->getOperand(0).getOperand(0), ShOpc, 2684 getAL(CurDAG, dl), Reg0, Reg0 }; 2685 CurDAG->SelectNodeTo(N, ARM::MOVsi, MVT::i32, Ops); 2686 return true; 2687 } 2688 2689 assert(LSB + Width + 1 <= 32 && "Shouldn't create an invalid ubfx"); 2690 SDValue Ops[] = { N->getOperand(0).getOperand(0), 2691 CurDAG->getTargetConstant(LSB, dl, MVT::i32), 2692 CurDAG->getTargetConstant(Width, dl, MVT::i32), 2693 getAL(CurDAG, dl), Reg0 }; 2694 CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2695 return true; 2696 } 2697 } 2698 return false; 2699 } 2700 2701 // Otherwise, we're looking for a shift of a shift 2702 unsigned Shl_imm = 0; 2703 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, Shl_imm)) { 2704 assert(Shl_imm > 0 && Shl_imm < 32 && "bad amount in shift node!"); 2705 unsigned Srl_imm = 0; 2706 if (isInt32Immediate(N->getOperand(1), Srl_imm)) { 2707 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 2708 // Note: The width operand is encoded as width-1. 2709 unsigned Width = 32 - Srl_imm - 1; 2710 int LSB = Srl_imm - Shl_imm; 2711 if (LSB < 0) 2712 return false; 2713 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2714 assert(LSB + Width + 1 <= 32 && "Shouldn't create an invalid ubfx"); 2715 SDValue Ops[] = { N->getOperand(0).getOperand(0), 2716 CurDAG->getTargetConstant(LSB, dl, MVT::i32), 2717 CurDAG->getTargetConstant(Width, dl, MVT::i32), 2718 getAL(CurDAG, dl), Reg0 }; 2719 CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2720 return true; 2721 } 2722 } 2723 2724 // Or we are looking for a shift of an and, with a mask operand 2725 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::AND, And_imm) && 2726 isShiftedMask_32(And_imm)) { 2727 unsigned Srl_imm = 0; 2728 unsigned LSB = countTrailingZeros(And_imm); 2729 // Shift must be the same as the ands lsb 2730 if (isInt32Immediate(N->getOperand(1), Srl_imm) && Srl_imm == LSB) { 2731 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 2732 unsigned MSB = 31 - countLeadingZeros(And_imm); 2733 // Note: The width operand is encoded as width-1. 2734 unsigned Width = MSB - LSB; 2735 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2736 assert(Srl_imm + Width + 1 <= 32 && "Shouldn't create an invalid ubfx"); 2737 SDValue Ops[] = { N->getOperand(0).getOperand(0), 2738 CurDAG->getTargetConstant(Srl_imm, dl, MVT::i32), 2739 CurDAG->getTargetConstant(Width, dl, MVT::i32), 2740 getAL(CurDAG, dl), Reg0 }; 2741 CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2742 return true; 2743 } 2744 } 2745 2746 if (N->getOpcode() == ISD::SIGN_EXTEND_INREG) { 2747 unsigned Width = cast<VTSDNode>(N->getOperand(1))->getVT().getSizeInBits(); 2748 unsigned LSB = 0; 2749 if (!isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRL, LSB) && 2750 !isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRA, LSB)) 2751 return false; 2752 2753 if (LSB + Width > 32) 2754 return false; 2755 2756 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2757 assert(LSB + Width <= 32 && "Shouldn't create an invalid ubfx"); 2758 SDValue Ops[] = { N->getOperand(0).getOperand(0), 2759 CurDAG->getTargetConstant(LSB, dl, MVT::i32), 2760 CurDAG->getTargetConstant(Width - 1, dl, MVT::i32), 2761 getAL(CurDAG, dl), Reg0 }; 2762 CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2763 return true; 2764 } 2765 2766 return false; 2767 } 2768 2769 /// Target-specific DAG combining for ISD::XOR. 2770 /// Target-independent combining lowers SELECT_CC nodes of the form 2771 /// select_cc setg[ge] X, 0, X, -X 2772 /// select_cc setgt X, -1, X, -X 2773 /// select_cc setl[te] X, 0, -X, X 2774 /// select_cc setlt X, 1, -X, X 2775 /// which represent Integer ABS into: 2776 /// Y = sra (X, size(X)-1); xor (add (X, Y), Y) 2777 /// ARM instruction selection detects the latter and matches it to 2778 /// ARM::ABS or ARM::t2ABS machine node. 2779 bool ARMDAGToDAGISel::tryABSOp(SDNode *N){ 2780 SDValue XORSrc0 = N->getOperand(0); 2781 SDValue XORSrc1 = N->getOperand(1); 2782 EVT VT = N->getValueType(0); 2783 2784 if (Subtarget->isThumb1Only()) 2785 return false; 2786 2787 if (XORSrc0.getOpcode() != ISD::ADD || XORSrc1.getOpcode() != ISD::SRA) 2788 return false; 2789 2790 SDValue ADDSrc0 = XORSrc0.getOperand(0); 2791 SDValue ADDSrc1 = XORSrc0.getOperand(1); 2792 SDValue SRASrc0 = XORSrc1.getOperand(0); 2793 SDValue SRASrc1 = XORSrc1.getOperand(1); 2794 ConstantSDNode *SRAConstant = dyn_cast<ConstantSDNode>(SRASrc1); 2795 EVT XType = SRASrc0.getValueType(); 2796 unsigned Size = XType.getSizeInBits() - 1; 2797 2798 if (ADDSrc1 == XORSrc1 && ADDSrc0 == SRASrc0 && 2799 XType.isInteger() && SRAConstant != nullptr && 2800 Size == SRAConstant->getZExtValue()) { 2801 unsigned Opcode = Subtarget->isThumb2() ? ARM::t2ABS : ARM::ABS; 2802 CurDAG->SelectNodeTo(N, Opcode, VT, ADDSrc0); 2803 return true; 2804 } 2805 2806 return false; 2807 } 2808 2809 /// We've got special pseudo-instructions for these 2810 void ARMDAGToDAGISel::SelectCMP_SWAP(SDNode *N) { 2811 unsigned Opcode; 2812 EVT MemTy = cast<MemSDNode>(N)->getMemoryVT(); 2813 if (MemTy == MVT::i8) 2814 Opcode = ARM::CMP_SWAP_8; 2815 else if (MemTy == MVT::i16) 2816 Opcode = ARM::CMP_SWAP_16; 2817 else if (MemTy == MVT::i32) 2818 Opcode = ARM::CMP_SWAP_32; 2819 else 2820 llvm_unreachable("Unknown AtomicCmpSwap type"); 2821 2822 SDValue Ops[] = {N->getOperand(1), N->getOperand(2), N->getOperand(3), 2823 N->getOperand(0)}; 2824 SDNode *CmpSwap = CurDAG->getMachineNode( 2825 Opcode, SDLoc(N), 2826 CurDAG->getVTList(MVT::i32, MVT::i32, MVT::Other), Ops); 2827 2828 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand(); 2829 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp}); 2830 2831 ReplaceUses(SDValue(N, 0), SDValue(CmpSwap, 0)); 2832 ReplaceUses(SDValue(N, 1), SDValue(CmpSwap, 2)); 2833 CurDAG->RemoveDeadNode(N); 2834 } 2835 2836 static Optional<std::pair<unsigned, unsigned>> 2837 getContiguousRangeOfSetBits(const APInt &A) { 2838 unsigned FirstOne = A.getBitWidth() - A.countLeadingZeros() - 1; 2839 unsigned LastOne = A.countTrailingZeros(); 2840 if (A.countPopulation() != (FirstOne - LastOne + 1)) 2841 return Optional<std::pair<unsigned,unsigned>>(); 2842 return std::make_pair(FirstOne, LastOne); 2843 } 2844 2845 void ARMDAGToDAGISel::SelectCMPZ(SDNode *N, bool &SwitchEQNEToPLMI) { 2846 assert(N->getOpcode() == ARMISD::CMPZ); 2847 SwitchEQNEToPLMI = false; 2848 2849 if (!Subtarget->isThumb()) 2850 // FIXME: Work out whether it is profitable to do this in A32 mode - LSL and 2851 // LSR don't exist as standalone instructions - they need the barrel shifter. 2852 return; 2853 2854 // select (cmpz (and X, C), #0) -> (LSLS X) or (LSRS X) or (LSRS (LSLS X)) 2855 SDValue And = N->getOperand(0); 2856 if (!And->hasOneUse()) 2857 return; 2858 2859 SDValue Zero = N->getOperand(1); 2860 if (!isa<ConstantSDNode>(Zero) || !cast<ConstantSDNode>(Zero)->isNullValue() || 2861 And->getOpcode() != ISD::AND) 2862 return; 2863 SDValue X = And.getOperand(0); 2864 auto C = dyn_cast<ConstantSDNode>(And.getOperand(1)); 2865 2866 if (!C) 2867 return; 2868 auto Range = getContiguousRangeOfSetBits(C->getAPIntValue()); 2869 if (!Range) 2870 return; 2871 2872 // There are several ways to lower this: 2873 SDNode *NewN; 2874 SDLoc dl(N); 2875 2876 auto EmitShift = [&](unsigned Opc, SDValue Src, unsigned Imm) -> SDNode* { 2877 if (Subtarget->isThumb2()) { 2878 Opc = (Opc == ARM::tLSLri) ? ARM::t2LSLri : ARM::t2LSRri; 2879 SDValue Ops[] = { Src, CurDAG->getTargetConstant(Imm, dl, MVT::i32), 2880 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32), 2881 CurDAG->getRegister(0, MVT::i32) }; 2882 return CurDAG->getMachineNode(Opc, dl, MVT::i32, Ops); 2883 } else { 2884 SDValue Ops[] = {CurDAG->getRegister(ARM::CPSR, MVT::i32), Src, 2885 CurDAG->getTargetConstant(Imm, dl, MVT::i32), 2886 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32)}; 2887 return CurDAG->getMachineNode(Opc, dl, MVT::i32, Ops); 2888 } 2889 }; 2890 2891 if (Range->second == 0) { 2892 // 1. Mask includes the LSB -> Simply shift the top N bits off 2893 NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first); 2894 ReplaceNode(And.getNode(), NewN); 2895 } else if (Range->first == 31) { 2896 // 2. Mask includes the MSB -> Simply shift the bottom N bits off 2897 NewN = EmitShift(ARM::tLSRri, X, Range->second); 2898 ReplaceNode(And.getNode(), NewN); 2899 } else if (Range->first == Range->second) { 2900 // 3. Only one bit is set. We can shift this into the sign bit and use a 2901 // PL/MI comparison. 2902 NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first); 2903 ReplaceNode(And.getNode(), NewN); 2904 2905 SwitchEQNEToPLMI = true; 2906 } else if (!Subtarget->hasV6T2Ops()) { 2907 // 4. Do a double shift to clear bottom and top bits, but only in 2908 // thumb-1 mode as in thumb-2 we can use UBFX. 2909 NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first); 2910 NewN = EmitShift(ARM::tLSRri, SDValue(NewN, 0), 2911 Range->second + (31 - Range->first)); 2912 ReplaceNode(And.getNode(), NewN); 2913 } 2914 2915 } 2916 2917 void ARMDAGToDAGISel::Select(SDNode *N) { 2918 SDLoc dl(N); 2919 2920 if (N->isMachineOpcode()) { 2921 N->setNodeId(-1); 2922 return; // Already selected. 2923 } 2924 2925 switch (N->getOpcode()) { 2926 default: break; 2927 case ISD::STORE: { 2928 // For Thumb1, match an sp-relative store in C++. This is a little 2929 // unfortunate, but I don't think I can make the chain check work 2930 // otherwise. (The chain of the store has to be the same as the chain 2931 // of the CopyFromReg, or else we can't replace the CopyFromReg with 2932 // a direct reference to "SP".) 2933 // 2934 // This is only necessary on Thumb1 because Thumb1 sp-relative stores use 2935 // a different addressing mode from other four-byte stores. 2936 // 2937 // This pattern usually comes up with call arguments. 2938 StoreSDNode *ST = cast<StoreSDNode>(N); 2939 SDValue Ptr = ST->getBasePtr(); 2940 if (Subtarget->isThumb1Only() && ST->isUnindexed()) { 2941 int RHSC = 0; 2942 if (Ptr.getOpcode() == ISD::ADD && 2943 isScaledConstantInRange(Ptr.getOperand(1), /*Scale=*/4, 0, 256, RHSC)) 2944 Ptr = Ptr.getOperand(0); 2945 2946 if (Ptr.getOpcode() == ISD::CopyFromReg && 2947 cast<RegisterSDNode>(Ptr.getOperand(1))->getReg() == ARM::SP && 2948 Ptr.getOperand(0) == ST->getChain()) { 2949 SDValue Ops[] = {ST->getValue(), 2950 CurDAG->getRegister(ARM::SP, MVT::i32), 2951 CurDAG->getTargetConstant(RHSC, dl, MVT::i32), 2952 getAL(CurDAG, dl), 2953 CurDAG->getRegister(0, MVT::i32), 2954 ST->getChain()}; 2955 MachineSDNode *ResNode = 2956 CurDAG->getMachineNode(ARM::tSTRspi, dl, MVT::Other, Ops); 2957 MachineMemOperand *MemOp = ST->getMemOperand(); 2958 CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {MemOp}); 2959 ReplaceNode(N, ResNode); 2960 return; 2961 } 2962 } 2963 break; 2964 } 2965 case ISD::WRITE_REGISTER: 2966 if (tryWriteRegister(N)) 2967 return; 2968 break; 2969 case ISD::READ_REGISTER: 2970 if (tryReadRegister(N)) 2971 return; 2972 break; 2973 case ISD::INLINEASM: 2974 case ISD::INLINEASM_BR: 2975 if (tryInlineAsm(N)) 2976 return; 2977 break; 2978 case ISD::XOR: 2979 // Select special operations if XOR node forms integer ABS pattern 2980 if (tryABSOp(N)) 2981 return; 2982 // Other cases are autogenerated. 2983 break; 2984 case ISD::Constant: { 2985 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 2986 // If we can't materialize the constant we need to use a literal pool 2987 if (ConstantMaterializationCost(Val, Subtarget) > 2) { 2988 SDValue CPIdx = CurDAG->getTargetConstantPool( 2989 ConstantInt::get(Type::getInt32Ty(*CurDAG->getContext()), Val), 2990 TLI->getPointerTy(CurDAG->getDataLayout())); 2991 2992 SDNode *ResNode; 2993 if (Subtarget->isThumb()) { 2994 SDValue Ops[] = { 2995 CPIdx, 2996 getAL(CurDAG, dl), 2997 CurDAG->getRegister(0, MVT::i32), 2998 CurDAG->getEntryNode() 2999 }; 3000 ResNode = CurDAG->getMachineNode(ARM::tLDRpci, dl, MVT::i32, MVT::Other, 3001 Ops); 3002 } else { 3003 SDValue Ops[] = { 3004 CPIdx, 3005 CurDAG->getTargetConstant(0, dl, MVT::i32), 3006 getAL(CurDAG, dl), 3007 CurDAG->getRegister(0, MVT::i32), 3008 CurDAG->getEntryNode() 3009 }; 3010 ResNode = CurDAG->getMachineNode(ARM::LDRcp, dl, MVT::i32, MVT::Other, 3011 Ops); 3012 } 3013 // Annotate the Node with memory operand information so that MachineInstr 3014 // queries work properly. This e.g. gives the register allocation the 3015 // required information for rematerialization. 3016 MachineFunction& MF = CurDAG->getMachineFunction(); 3017 MachineMemOperand *MemOp = 3018 MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF), 3019 MachineMemOperand::MOLoad, 4, 4); 3020 3021 CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {MemOp}); 3022 3023 ReplaceNode(N, ResNode); 3024 return; 3025 } 3026 3027 // Other cases are autogenerated. 3028 break; 3029 } 3030 case ISD::FrameIndex: { 3031 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. 3032 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 3033 SDValue TFI = CurDAG->getTargetFrameIndex( 3034 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 3035 if (Subtarget->isThumb1Only()) { 3036 // Set the alignment of the frame object to 4, to avoid having to generate 3037 // more than one ADD 3038 MachineFrameInfo &MFI = MF->getFrameInfo(); 3039 if (MFI.getObjectAlignment(FI) < 4) 3040 MFI.setObjectAlignment(FI, 4); 3041 CurDAG->SelectNodeTo(N, ARM::tADDframe, MVT::i32, TFI, 3042 CurDAG->getTargetConstant(0, dl, MVT::i32)); 3043 return; 3044 } else { 3045 unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ? 3046 ARM::t2ADDri : ARM::ADDri); 3047 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, dl, MVT::i32), 3048 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32), 3049 CurDAG->getRegister(0, MVT::i32) }; 3050 CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 3051 return; 3052 } 3053 } 3054 case ISD::SRL: 3055 if (tryV6T2BitfieldExtractOp(N, false)) 3056 return; 3057 break; 3058 case ISD::SIGN_EXTEND_INREG: 3059 case ISD::SRA: 3060 if (tryV6T2BitfieldExtractOp(N, true)) 3061 return; 3062 break; 3063 case ISD::MUL: 3064 if (Subtarget->isThumb1Only()) 3065 break; 3066 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) { 3067 unsigned RHSV = C->getZExtValue(); 3068 if (!RHSV) break; 3069 if (isPowerOf2_32(RHSV-1)) { // 2^n+1? 3070 unsigned ShImm = Log2_32(RHSV-1); 3071 if (ShImm >= 32) 3072 break; 3073 SDValue V = N->getOperand(0); 3074 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 3075 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, dl, MVT::i32); 3076 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 3077 if (Subtarget->isThumb()) { 3078 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG, dl), Reg0, Reg0 }; 3079 CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops); 3080 return; 3081 } else { 3082 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG, dl), Reg0, 3083 Reg0 }; 3084 CurDAG->SelectNodeTo(N, ARM::ADDrsi, MVT::i32, Ops); 3085 return; 3086 } 3087 } 3088 if (isPowerOf2_32(RHSV+1)) { // 2^n-1? 3089 unsigned ShImm = Log2_32(RHSV+1); 3090 if (ShImm >= 32) 3091 break; 3092 SDValue V = N->getOperand(0); 3093 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 3094 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, dl, MVT::i32); 3095 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 3096 if (Subtarget->isThumb()) { 3097 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG, dl), Reg0, Reg0 }; 3098 CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops); 3099 return; 3100 } else { 3101 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG, dl), Reg0, 3102 Reg0 }; 3103 CurDAG->SelectNodeTo(N, ARM::RSBrsi, MVT::i32, Ops); 3104 return; 3105 } 3106 } 3107 } 3108 break; 3109 case ISD::AND: { 3110 // Check for unsigned bitfield extract 3111 if (tryV6T2BitfieldExtractOp(N, false)) 3112 return; 3113 3114 // If an immediate is used in an AND node, it is possible that the immediate 3115 // can be more optimally materialized when negated. If this is the case we 3116 // can negate the immediate and use a BIC instead. 3117 auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1)); 3118 if (N1C && N1C->hasOneUse() && Subtarget->isThumb()) { 3119 uint32_t Imm = (uint32_t) N1C->getZExtValue(); 3120 3121 // In Thumb2 mode, an AND can take a 12-bit immediate. If this 3122 // immediate can be negated and fit in the immediate operand of 3123 // a t2BIC, don't do any manual transform here as this can be 3124 // handled by the generic ISel machinery. 3125 bool PreferImmediateEncoding = 3126 Subtarget->hasThumb2() && (is_t2_so_imm(Imm) || is_t2_so_imm_not(Imm)); 3127 if (!PreferImmediateEncoding && 3128 ConstantMaterializationCost(Imm, Subtarget) > 3129 ConstantMaterializationCost(~Imm, Subtarget)) { 3130 // The current immediate costs more to materialize than a negated 3131 // immediate, so negate the immediate and use a BIC. 3132 SDValue NewImm = 3133 CurDAG->getConstant(~N1C->getZExtValue(), dl, MVT::i32); 3134 // If the new constant didn't exist before, reposition it in the topological 3135 // ordering so it is just before N. Otherwise, don't touch its location. 3136 if (NewImm->getNodeId() == -1) 3137 CurDAG->RepositionNode(N->getIterator(), NewImm.getNode()); 3138 3139 if (!Subtarget->hasThumb2()) { 3140 SDValue Ops[] = {CurDAG->getRegister(ARM::CPSR, MVT::i32), 3141 N->getOperand(0), NewImm, getAL(CurDAG, dl), 3142 CurDAG->getRegister(0, MVT::i32)}; 3143 ReplaceNode(N, CurDAG->getMachineNode(ARM::tBIC, dl, MVT::i32, Ops)); 3144 return; 3145 } else { 3146 SDValue Ops[] = {N->getOperand(0), NewImm, getAL(CurDAG, dl), 3147 CurDAG->getRegister(0, MVT::i32), 3148 CurDAG->getRegister(0, MVT::i32)}; 3149 ReplaceNode(N, 3150 CurDAG->getMachineNode(ARM::t2BICrr, dl, MVT::i32, Ops)); 3151 return; 3152 } 3153 } 3154 } 3155 3156 // (and (or x, c2), c1) and top 16-bits of c1 and c2 match, lower 16-bits 3157 // of c1 are 0xffff, and lower 16-bit of c2 are 0. That is, the top 16-bits 3158 // are entirely contributed by c2 and lower 16-bits are entirely contributed 3159 // by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)). 3160 // Select it to: "movt x, ((c1 & 0xffff) >> 16) 3161 EVT VT = N->getValueType(0); 3162 if (VT != MVT::i32) 3163 break; 3164 unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2()) 3165 ? ARM::t2MOVTi16 3166 : (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0); 3167 if (!Opc) 3168 break; 3169 SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); 3170 N1C = dyn_cast<ConstantSDNode>(N1); 3171 if (!N1C) 3172 break; 3173 if (N0.getOpcode() == ISD::OR && N0.getNode()->hasOneUse()) { 3174 SDValue N2 = N0.getOperand(1); 3175 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2); 3176 if (!N2C) 3177 break; 3178 unsigned N1CVal = N1C->getZExtValue(); 3179 unsigned N2CVal = N2C->getZExtValue(); 3180 if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) && 3181 (N1CVal & 0xffffU) == 0xffffU && 3182 (N2CVal & 0xffffU) == 0x0U) { 3183 SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16, 3184 dl, MVT::i32); 3185 SDValue Ops[] = { N0.getOperand(0), Imm16, 3186 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32) }; 3187 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, Ops)); 3188 return; 3189 } 3190 } 3191 3192 break; 3193 } 3194 case ARMISD::UMAAL: { 3195 unsigned Opc = Subtarget->isThumb() ? ARM::t2UMAAL : ARM::UMAAL; 3196 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 3197 N->getOperand(2), N->getOperand(3), 3198 getAL(CurDAG, dl), 3199 CurDAG->getRegister(0, MVT::i32) }; 3200 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, MVT::i32, MVT::i32, Ops)); 3201 return; 3202 } 3203 case ARMISD::UMLAL:{ 3204 if (Subtarget->isThumb()) { 3205 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), 3206 N->getOperand(3), getAL(CurDAG, dl), 3207 CurDAG->getRegister(0, MVT::i32)}; 3208 ReplaceNode( 3209 N, CurDAG->getMachineNode(ARM::t2UMLAL, dl, MVT::i32, MVT::i32, Ops)); 3210 return; 3211 }else{ 3212 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), 3213 N->getOperand(3), getAL(CurDAG, dl), 3214 CurDAG->getRegister(0, MVT::i32), 3215 CurDAG->getRegister(0, MVT::i32) }; 3216 ReplaceNode(N, CurDAG->getMachineNode( 3217 Subtarget->hasV6Ops() ? ARM::UMLAL : ARM::UMLALv5, dl, 3218 MVT::i32, MVT::i32, Ops)); 3219 return; 3220 } 3221 } 3222 case ARMISD::SMLAL:{ 3223 if (Subtarget->isThumb()) { 3224 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), 3225 N->getOperand(3), getAL(CurDAG, dl), 3226 CurDAG->getRegister(0, MVT::i32)}; 3227 ReplaceNode( 3228 N, CurDAG->getMachineNode(ARM::t2SMLAL, dl, MVT::i32, MVT::i32, Ops)); 3229 return; 3230 }else{ 3231 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), 3232 N->getOperand(3), getAL(CurDAG, dl), 3233 CurDAG->getRegister(0, MVT::i32), 3234 CurDAG->getRegister(0, MVT::i32) }; 3235 ReplaceNode(N, CurDAG->getMachineNode( 3236 Subtarget->hasV6Ops() ? ARM::SMLAL : ARM::SMLALv5, dl, 3237 MVT::i32, MVT::i32, Ops)); 3238 return; 3239 } 3240 } 3241 case ARMISD::SUBE: { 3242 if (!Subtarget->hasV6Ops() || !Subtarget->hasDSP()) 3243 break; 3244 // Look for a pattern to match SMMLS 3245 // (sube a, (smul_loHi a, b), (subc 0, (smul_LOhi(a, b)))) 3246 if (N->getOperand(1).getOpcode() != ISD::SMUL_LOHI || 3247 N->getOperand(2).getOpcode() != ARMISD::SUBC || 3248 !SDValue(N, 1).use_empty()) 3249 break; 3250 3251 if (Subtarget->isThumb()) 3252 assert(Subtarget->hasThumb2() && 3253 "This pattern should not be generated for Thumb"); 3254 3255 SDValue SmulLoHi = N->getOperand(1); 3256 SDValue Subc = N->getOperand(2); 3257 auto *Zero = dyn_cast<ConstantSDNode>(Subc.getOperand(0)); 3258 3259 if (!Zero || Zero->getZExtValue() != 0 || 3260 Subc.getOperand(1) != SmulLoHi.getValue(0) || 3261 N->getOperand(1) != SmulLoHi.getValue(1) || 3262 N->getOperand(2) != Subc.getValue(1)) 3263 break; 3264 3265 unsigned Opc = Subtarget->isThumb2() ? ARM::t2SMMLS : ARM::SMMLS; 3266 SDValue Ops[] = { SmulLoHi.getOperand(0), SmulLoHi.getOperand(1), 3267 N->getOperand(0), getAL(CurDAG, dl), 3268 CurDAG->getRegister(0, MVT::i32) }; 3269 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, MVT::i32, Ops)); 3270 return; 3271 } 3272 case ISD::LOAD: { 3273 if (Subtarget->hasMVEIntegerOps() && tryMVEIndexedLoad(N)) 3274 return; 3275 if (Subtarget->isThumb() && Subtarget->hasThumb2()) { 3276 if (tryT2IndexedLoad(N)) 3277 return; 3278 } else if (Subtarget->isThumb()) { 3279 if (tryT1IndexedLoad(N)) 3280 return; 3281 } else if (tryARMIndexedLoad(N)) 3282 return; 3283 // Other cases are autogenerated. 3284 break; 3285 } 3286 case ARMISD::WLS: 3287 case ARMISD::LE: { 3288 SDValue Ops[] = { N->getOperand(1), 3289 N->getOperand(2), 3290 N->getOperand(0) }; 3291 unsigned Opc = N->getOpcode() == ARMISD::WLS ? 3292 ARM::t2WhileLoopStart : ARM::t2LoopEnd; 3293 SDNode *New = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops); 3294 ReplaceUses(N, New); 3295 CurDAG->RemoveDeadNode(N); 3296 return; 3297 } 3298 case ARMISD::LOOP_DEC: { 3299 SDValue Ops[] = { N->getOperand(1), 3300 N->getOperand(2), 3301 N->getOperand(0) }; 3302 SDNode *Dec = 3303 CurDAG->getMachineNode(ARM::t2LoopDec, dl, 3304 CurDAG->getVTList(MVT::i32, MVT::Other), Ops); 3305 ReplaceUses(N, Dec); 3306 CurDAG->RemoveDeadNode(N); 3307 return; 3308 } 3309 case ARMISD::BRCOND: { 3310 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 3311 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc) 3312 // Pattern complexity = 6 cost = 1 size = 0 3313 3314 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 3315 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc) 3316 // Pattern complexity = 6 cost = 1 size = 0 3317 3318 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 3319 // Emits: (t2Bcc:void (bb:Other):$dst, (imm:i32):$cc) 3320 // Pattern complexity = 6 cost = 1 size = 0 3321 3322 unsigned Opc = Subtarget->isThumb() ? 3323 ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; 3324 SDValue Chain = N->getOperand(0); 3325 SDValue N1 = N->getOperand(1); 3326 SDValue N2 = N->getOperand(2); 3327 SDValue N3 = N->getOperand(3); 3328 SDValue InFlag = N->getOperand(4); 3329 assert(N1.getOpcode() == ISD::BasicBlock); 3330 assert(N2.getOpcode() == ISD::Constant); 3331 assert(N3.getOpcode() == ISD::Register); 3332 3333 unsigned CC = (unsigned) cast<ConstantSDNode>(N2)->getZExtValue(); 3334 3335 if (InFlag.getOpcode() == ARMISD::CMPZ) { 3336 if (InFlag.getOperand(0).getOpcode() == ISD::INTRINSIC_W_CHAIN) { 3337 SDValue Int = InFlag.getOperand(0); 3338 uint64_t ID = cast<ConstantSDNode>(Int->getOperand(1))->getZExtValue(); 3339 3340 // Handle low-overhead loops. 3341 if (ID == Intrinsic::loop_decrement_reg) { 3342 SDValue Elements = Int.getOperand(2); 3343 SDValue Size = CurDAG->getTargetConstant( 3344 cast<ConstantSDNode>(Int.getOperand(3))->getZExtValue(), dl, 3345 MVT::i32); 3346 3347 SDValue Args[] = { Elements, Size, Int.getOperand(0) }; 3348 SDNode *LoopDec = 3349 CurDAG->getMachineNode(ARM::t2LoopDec, dl, 3350 CurDAG->getVTList(MVT::i32, MVT::Other), 3351 Args); 3352 ReplaceUses(Int.getNode(), LoopDec); 3353 3354 SDValue EndArgs[] = { SDValue(LoopDec, 0), N1, Chain }; 3355 SDNode *LoopEnd = 3356 CurDAG->getMachineNode(ARM::t2LoopEnd, dl, MVT::Other, EndArgs); 3357 3358 ReplaceUses(N, LoopEnd); 3359 CurDAG->RemoveDeadNode(N); 3360 CurDAG->RemoveDeadNode(InFlag.getNode()); 3361 CurDAG->RemoveDeadNode(Int.getNode()); 3362 return; 3363 } 3364 } 3365 3366 bool SwitchEQNEToPLMI; 3367 SelectCMPZ(InFlag.getNode(), SwitchEQNEToPLMI); 3368 InFlag = N->getOperand(4); 3369 3370 if (SwitchEQNEToPLMI) { 3371 switch ((ARMCC::CondCodes)CC) { 3372 default: llvm_unreachable("CMPZ must be either NE or EQ!"); 3373 case ARMCC::NE: 3374 CC = (unsigned)ARMCC::MI; 3375 break; 3376 case ARMCC::EQ: 3377 CC = (unsigned)ARMCC::PL; 3378 break; 3379 } 3380 } 3381 } 3382 3383 SDValue Tmp2 = CurDAG->getTargetConstant(CC, dl, MVT::i32); 3384 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; 3385 SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, 3386 MVT::Glue, Ops); 3387 Chain = SDValue(ResNode, 0); 3388 if (N->getNumValues() == 2) { 3389 InFlag = SDValue(ResNode, 1); 3390 ReplaceUses(SDValue(N, 1), InFlag); 3391 } 3392 ReplaceUses(SDValue(N, 0), 3393 SDValue(Chain.getNode(), Chain.getResNo())); 3394 CurDAG->RemoveDeadNode(N); 3395 return; 3396 } 3397 3398 case ARMISD::CMPZ: { 3399 // select (CMPZ X, #-C) -> (CMPZ (ADDS X, #C), #0) 3400 // This allows us to avoid materializing the expensive negative constant. 3401 // The CMPZ #0 is useless and will be peepholed away but we need to keep it 3402 // for its glue output. 3403 SDValue X = N->getOperand(0); 3404 auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1).getNode()); 3405 if (C && C->getSExtValue() < 0 && Subtarget->isThumb()) { 3406 int64_t Addend = -C->getSExtValue(); 3407 3408 SDNode *Add = nullptr; 3409 // ADDS can be better than CMN if the immediate fits in a 3410 // 16-bit ADDS, which means either [0,256) for tADDi8 or [0,8) for tADDi3. 3411 // Outside that range we can just use a CMN which is 32-bit but has a 3412 // 12-bit immediate range. 3413 if (Addend < 1<<8) { 3414 if (Subtarget->isThumb2()) { 3415 SDValue Ops[] = { X, CurDAG->getTargetConstant(Addend, dl, MVT::i32), 3416 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32), 3417 CurDAG->getRegister(0, MVT::i32) }; 3418 Add = CurDAG->getMachineNode(ARM::t2ADDri, dl, MVT::i32, Ops); 3419 } else { 3420 unsigned Opc = (Addend < 1<<3) ? ARM::tADDi3 : ARM::tADDi8; 3421 SDValue Ops[] = {CurDAG->getRegister(ARM::CPSR, MVT::i32), X, 3422 CurDAG->getTargetConstant(Addend, dl, MVT::i32), 3423 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32)}; 3424 Add = CurDAG->getMachineNode(Opc, dl, MVT::i32, Ops); 3425 } 3426 } 3427 if (Add) { 3428 SDValue Ops2[] = {SDValue(Add, 0), CurDAG->getConstant(0, dl, MVT::i32)}; 3429 CurDAG->MorphNodeTo(N, ARMISD::CMPZ, CurDAG->getVTList(MVT::Glue), Ops2); 3430 } 3431 } 3432 // Other cases are autogenerated. 3433 break; 3434 } 3435 3436 case ARMISD::CMOV: { 3437 SDValue InFlag = N->getOperand(4); 3438 3439 if (InFlag.getOpcode() == ARMISD::CMPZ) { 3440 bool SwitchEQNEToPLMI; 3441 SelectCMPZ(InFlag.getNode(), SwitchEQNEToPLMI); 3442 3443 if (SwitchEQNEToPLMI) { 3444 SDValue ARMcc = N->getOperand(2); 3445 ARMCC::CondCodes CC = 3446 (ARMCC::CondCodes)cast<ConstantSDNode>(ARMcc)->getZExtValue(); 3447 3448 switch (CC) { 3449 default: llvm_unreachable("CMPZ must be either NE or EQ!"); 3450 case ARMCC::NE: 3451 CC = ARMCC::MI; 3452 break; 3453 case ARMCC::EQ: 3454 CC = ARMCC::PL; 3455 break; 3456 } 3457 SDValue NewARMcc = CurDAG->getConstant((unsigned)CC, dl, MVT::i32); 3458 SDValue Ops[] = {N->getOperand(0), N->getOperand(1), NewARMcc, 3459 N->getOperand(3), N->getOperand(4)}; 3460 CurDAG->MorphNodeTo(N, ARMISD::CMOV, N->getVTList(), Ops); 3461 } 3462 3463 } 3464 // Other cases are autogenerated. 3465 break; 3466 } 3467 3468 case ARMISD::VZIP: { 3469 unsigned Opc = 0; 3470 EVT VT = N->getValueType(0); 3471 switch (VT.getSimpleVT().SimpleTy) { 3472 default: return; 3473 case MVT::v8i8: Opc = ARM::VZIPd8; break; 3474 case MVT::v4f16: 3475 case MVT::v4i16: Opc = ARM::VZIPd16; break; 3476 case MVT::v2f32: 3477 // vzip.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm. 3478 case MVT::v2i32: Opc = ARM::VTRNd32; break; 3479 case MVT::v16i8: Opc = ARM::VZIPq8; break; 3480 case MVT::v8f16: 3481 case MVT::v8i16: Opc = ARM::VZIPq16; break; 3482 case MVT::v4f32: 3483 case MVT::v4i32: Opc = ARM::VZIPq32; break; 3484 } 3485 SDValue Pred = getAL(CurDAG, dl); 3486 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 3487 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 3488 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, VT, Ops)); 3489 return; 3490 } 3491 case ARMISD::VUZP: { 3492 unsigned Opc = 0; 3493 EVT VT = N->getValueType(0); 3494 switch (VT.getSimpleVT().SimpleTy) { 3495 default: return; 3496 case MVT::v8i8: Opc = ARM::VUZPd8; break; 3497 case MVT::v4f16: 3498 case MVT::v4i16: Opc = ARM::VUZPd16; break; 3499 case MVT::v2f32: 3500 // vuzp.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm. 3501 case MVT::v2i32: Opc = ARM::VTRNd32; break; 3502 case MVT::v16i8: Opc = ARM::VUZPq8; break; 3503 case MVT::v8f16: 3504 case MVT::v8i16: Opc = ARM::VUZPq16; break; 3505 case MVT::v4f32: 3506 case MVT::v4i32: Opc = ARM::VUZPq32; break; 3507 } 3508 SDValue Pred = getAL(CurDAG, dl); 3509 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 3510 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 3511 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, VT, Ops)); 3512 return; 3513 } 3514 case ARMISD::VTRN: { 3515 unsigned Opc = 0; 3516 EVT VT = N->getValueType(0); 3517 switch (VT.getSimpleVT().SimpleTy) { 3518 default: return; 3519 case MVT::v8i8: Opc = ARM::VTRNd8; break; 3520 case MVT::v4f16: 3521 case MVT::v4i16: Opc = ARM::VTRNd16; break; 3522 case MVT::v2f32: 3523 case MVT::v2i32: Opc = ARM::VTRNd32; break; 3524 case MVT::v16i8: Opc = ARM::VTRNq8; break; 3525 case MVT::v8f16: 3526 case MVT::v8i16: Opc = ARM::VTRNq16; break; 3527 case MVT::v4f32: 3528 case MVT::v4i32: Opc = ARM::VTRNq32; break; 3529 } 3530 SDValue Pred = getAL(CurDAG, dl); 3531 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 3532 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 3533 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, VT, Ops)); 3534 return; 3535 } 3536 case ARMISD::BUILD_VECTOR: { 3537 EVT VecVT = N->getValueType(0); 3538 EVT EltVT = VecVT.getVectorElementType(); 3539 unsigned NumElts = VecVT.getVectorNumElements(); 3540 if (EltVT == MVT::f64) { 3541 assert(NumElts == 2 && "unexpected type for BUILD_VECTOR"); 3542 ReplaceNode( 3543 N, createDRegPairNode(VecVT, N->getOperand(0), N->getOperand(1))); 3544 return; 3545 } 3546 assert(EltVT == MVT::f32 && "unexpected type for BUILD_VECTOR"); 3547 if (NumElts == 2) { 3548 ReplaceNode( 3549 N, createSRegPairNode(VecVT, N->getOperand(0), N->getOperand(1))); 3550 return; 3551 } 3552 assert(NumElts == 4 && "unexpected type for BUILD_VECTOR"); 3553 ReplaceNode(N, 3554 createQuadSRegsNode(VecVT, N->getOperand(0), N->getOperand(1), 3555 N->getOperand(2), N->getOperand(3))); 3556 return; 3557 } 3558 3559 case ARMISD::VLD1DUP: { 3560 static const uint16_t DOpcodes[] = { ARM::VLD1DUPd8, ARM::VLD1DUPd16, 3561 ARM::VLD1DUPd32 }; 3562 static const uint16_t QOpcodes[] = { ARM::VLD1DUPq8, ARM::VLD1DUPq16, 3563 ARM::VLD1DUPq32 }; 3564 SelectVLDDup(N, /* IsIntrinsic= */ false, false, 1, DOpcodes, QOpcodes); 3565 return; 3566 } 3567 3568 case ARMISD::VLD2DUP: { 3569 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8, ARM::VLD2DUPd16, 3570 ARM::VLD2DUPd32 }; 3571 SelectVLDDup(N, /* IsIntrinsic= */ false, false, 2, Opcodes); 3572 return; 3573 } 3574 3575 case ARMISD::VLD3DUP: { 3576 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo, 3577 ARM::VLD3DUPd16Pseudo, 3578 ARM::VLD3DUPd32Pseudo }; 3579 SelectVLDDup(N, /* IsIntrinsic= */ false, false, 3, Opcodes); 3580 return; 3581 } 3582 3583 case ARMISD::VLD4DUP: { 3584 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo, 3585 ARM::VLD4DUPd16Pseudo, 3586 ARM::VLD4DUPd32Pseudo }; 3587 SelectVLDDup(N, /* IsIntrinsic= */ false, false, 4, Opcodes); 3588 return; 3589 } 3590 3591 case ARMISD::VLD1DUP_UPD: { 3592 static const uint16_t DOpcodes[] = { ARM::VLD1DUPd8wb_fixed, 3593 ARM::VLD1DUPd16wb_fixed, 3594 ARM::VLD1DUPd32wb_fixed }; 3595 static const uint16_t QOpcodes[] = { ARM::VLD1DUPq8wb_fixed, 3596 ARM::VLD1DUPq16wb_fixed, 3597 ARM::VLD1DUPq32wb_fixed }; 3598 SelectVLDDup(N, /* IsIntrinsic= */ false, true, 1, DOpcodes, QOpcodes); 3599 return; 3600 } 3601 3602 case ARMISD::VLD2DUP_UPD: { 3603 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8wb_fixed, 3604 ARM::VLD2DUPd16wb_fixed, 3605 ARM::VLD2DUPd32wb_fixed }; 3606 SelectVLDDup(N, /* IsIntrinsic= */ false, true, 2, Opcodes); 3607 return; 3608 } 3609 3610 case ARMISD::VLD3DUP_UPD: { 3611 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo_UPD, 3612 ARM::VLD3DUPd16Pseudo_UPD, 3613 ARM::VLD3DUPd32Pseudo_UPD }; 3614 SelectVLDDup(N, /* IsIntrinsic= */ false, true, 3, Opcodes); 3615 return; 3616 } 3617 3618 case ARMISD::VLD4DUP_UPD: { 3619 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo_UPD, 3620 ARM::VLD4DUPd16Pseudo_UPD, 3621 ARM::VLD4DUPd32Pseudo_UPD }; 3622 SelectVLDDup(N, /* IsIntrinsic= */ false, true, 4, Opcodes); 3623 return; 3624 } 3625 3626 case ARMISD::VLD1_UPD: { 3627 static const uint16_t DOpcodes[] = { ARM::VLD1d8wb_fixed, 3628 ARM::VLD1d16wb_fixed, 3629 ARM::VLD1d32wb_fixed, 3630 ARM::VLD1d64wb_fixed }; 3631 static const uint16_t QOpcodes[] = { ARM::VLD1q8wb_fixed, 3632 ARM::VLD1q16wb_fixed, 3633 ARM::VLD1q32wb_fixed, 3634 ARM::VLD1q64wb_fixed }; 3635 SelectVLD(N, true, 1, DOpcodes, QOpcodes, nullptr); 3636 return; 3637 } 3638 3639 case ARMISD::VLD2_UPD: { 3640 static const uint16_t DOpcodes[] = { ARM::VLD2d8wb_fixed, 3641 ARM::VLD2d16wb_fixed, 3642 ARM::VLD2d32wb_fixed, 3643 ARM::VLD1q64wb_fixed}; 3644 static const uint16_t QOpcodes[] = { ARM::VLD2q8PseudoWB_fixed, 3645 ARM::VLD2q16PseudoWB_fixed, 3646 ARM::VLD2q32PseudoWB_fixed }; 3647 SelectVLD(N, true, 2, DOpcodes, QOpcodes, nullptr); 3648 return; 3649 } 3650 3651 case ARMISD::VLD3_UPD: { 3652 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo_UPD, 3653 ARM::VLD3d16Pseudo_UPD, 3654 ARM::VLD3d32Pseudo_UPD, 3655 ARM::VLD1d64TPseudoWB_fixed}; 3656 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD, 3657 ARM::VLD3q16Pseudo_UPD, 3658 ARM::VLD3q32Pseudo_UPD }; 3659 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo_UPD, 3660 ARM::VLD3q16oddPseudo_UPD, 3661 ARM::VLD3q32oddPseudo_UPD }; 3662 SelectVLD(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1); 3663 return; 3664 } 3665 3666 case ARMISD::VLD4_UPD: { 3667 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo_UPD, 3668 ARM::VLD4d16Pseudo_UPD, 3669 ARM::VLD4d32Pseudo_UPD, 3670 ARM::VLD1d64QPseudoWB_fixed}; 3671 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD, 3672 ARM::VLD4q16Pseudo_UPD, 3673 ARM::VLD4q32Pseudo_UPD }; 3674 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo_UPD, 3675 ARM::VLD4q16oddPseudo_UPD, 3676 ARM::VLD4q32oddPseudo_UPD }; 3677 SelectVLD(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1); 3678 return; 3679 } 3680 3681 case ARMISD::VLD2LN_UPD: { 3682 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo_UPD, 3683 ARM::VLD2LNd16Pseudo_UPD, 3684 ARM::VLD2LNd32Pseudo_UPD }; 3685 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo_UPD, 3686 ARM::VLD2LNq32Pseudo_UPD }; 3687 SelectVLDSTLane(N, true, true, 2, DOpcodes, QOpcodes); 3688 return; 3689 } 3690 3691 case ARMISD::VLD3LN_UPD: { 3692 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo_UPD, 3693 ARM::VLD3LNd16Pseudo_UPD, 3694 ARM::VLD3LNd32Pseudo_UPD }; 3695 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo_UPD, 3696 ARM::VLD3LNq32Pseudo_UPD }; 3697 SelectVLDSTLane(N, true, true, 3, DOpcodes, QOpcodes); 3698 return; 3699 } 3700 3701 case ARMISD::VLD4LN_UPD: { 3702 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo_UPD, 3703 ARM::VLD4LNd16Pseudo_UPD, 3704 ARM::VLD4LNd32Pseudo_UPD }; 3705 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo_UPD, 3706 ARM::VLD4LNq32Pseudo_UPD }; 3707 SelectVLDSTLane(N, true, true, 4, DOpcodes, QOpcodes); 3708 return; 3709 } 3710 3711 case ARMISD::VST1_UPD: { 3712 static const uint16_t DOpcodes[] = { ARM::VST1d8wb_fixed, 3713 ARM::VST1d16wb_fixed, 3714 ARM::VST1d32wb_fixed, 3715 ARM::VST1d64wb_fixed }; 3716 static const uint16_t QOpcodes[] = { ARM::VST1q8wb_fixed, 3717 ARM::VST1q16wb_fixed, 3718 ARM::VST1q32wb_fixed, 3719 ARM::VST1q64wb_fixed }; 3720 SelectVST(N, true, 1, DOpcodes, QOpcodes, nullptr); 3721 return; 3722 } 3723 3724 case ARMISD::VST2_UPD: { 3725 static const uint16_t DOpcodes[] = { ARM::VST2d8wb_fixed, 3726 ARM::VST2d16wb_fixed, 3727 ARM::VST2d32wb_fixed, 3728 ARM::VST1q64wb_fixed}; 3729 static const uint16_t QOpcodes[] = { ARM::VST2q8PseudoWB_fixed, 3730 ARM::VST2q16PseudoWB_fixed, 3731 ARM::VST2q32PseudoWB_fixed }; 3732 SelectVST(N, true, 2, DOpcodes, QOpcodes, nullptr); 3733 return; 3734 } 3735 3736 case ARMISD::VST3_UPD: { 3737 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo_UPD, 3738 ARM::VST3d16Pseudo_UPD, 3739 ARM::VST3d32Pseudo_UPD, 3740 ARM::VST1d64TPseudoWB_fixed}; 3741 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD, 3742 ARM::VST3q16Pseudo_UPD, 3743 ARM::VST3q32Pseudo_UPD }; 3744 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo_UPD, 3745 ARM::VST3q16oddPseudo_UPD, 3746 ARM::VST3q32oddPseudo_UPD }; 3747 SelectVST(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1); 3748 return; 3749 } 3750 3751 case ARMISD::VST4_UPD: { 3752 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo_UPD, 3753 ARM::VST4d16Pseudo_UPD, 3754 ARM::VST4d32Pseudo_UPD, 3755 ARM::VST1d64QPseudoWB_fixed}; 3756 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD, 3757 ARM::VST4q16Pseudo_UPD, 3758 ARM::VST4q32Pseudo_UPD }; 3759 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo_UPD, 3760 ARM::VST4q16oddPseudo_UPD, 3761 ARM::VST4q32oddPseudo_UPD }; 3762 SelectVST(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1); 3763 return; 3764 } 3765 3766 case ARMISD::VST2LN_UPD: { 3767 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo_UPD, 3768 ARM::VST2LNd16Pseudo_UPD, 3769 ARM::VST2LNd32Pseudo_UPD }; 3770 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo_UPD, 3771 ARM::VST2LNq32Pseudo_UPD }; 3772 SelectVLDSTLane(N, false, true, 2, DOpcodes, QOpcodes); 3773 return; 3774 } 3775 3776 case ARMISD::VST3LN_UPD: { 3777 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo_UPD, 3778 ARM::VST3LNd16Pseudo_UPD, 3779 ARM::VST3LNd32Pseudo_UPD }; 3780 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo_UPD, 3781 ARM::VST3LNq32Pseudo_UPD }; 3782 SelectVLDSTLane(N, false, true, 3, DOpcodes, QOpcodes); 3783 return; 3784 } 3785 3786 case ARMISD::VST4LN_UPD: { 3787 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo_UPD, 3788 ARM::VST4LNd16Pseudo_UPD, 3789 ARM::VST4LNd32Pseudo_UPD }; 3790 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo_UPD, 3791 ARM::VST4LNq32Pseudo_UPD }; 3792 SelectVLDSTLane(N, false, true, 4, DOpcodes, QOpcodes); 3793 return; 3794 } 3795 3796 case ISD::INTRINSIC_VOID: 3797 case ISD::INTRINSIC_W_CHAIN: { 3798 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 3799 switch (IntNo) { 3800 default: 3801 break; 3802 3803 case Intrinsic::arm_mrrc: 3804 case Intrinsic::arm_mrrc2: { 3805 SDLoc dl(N); 3806 SDValue Chain = N->getOperand(0); 3807 unsigned Opc; 3808 3809 if (Subtarget->isThumb()) 3810 Opc = (IntNo == Intrinsic::arm_mrrc ? ARM::t2MRRC : ARM::t2MRRC2); 3811 else 3812 Opc = (IntNo == Intrinsic::arm_mrrc ? ARM::MRRC : ARM::MRRC2); 3813 3814 SmallVector<SDValue, 5> Ops; 3815 Ops.push_back(getI32Imm(cast<ConstantSDNode>(N->getOperand(2))->getZExtValue(), dl)); /* coproc */ 3816 Ops.push_back(getI32Imm(cast<ConstantSDNode>(N->getOperand(3))->getZExtValue(), dl)); /* opc */ 3817 Ops.push_back(getI32Imm(cast<ConstantSDNode>(N->getOperand(4))->getZExtValue(), dl)); /* CRm */ 3818 3819 // The mrrc2 instruction in ARM doesn't allow predicates, the top 4 bits of the encoded 3820 // instruction will always be '1111' but it is possible in assembly language to specify 3821 // AL as a predicate to mrrc2 but it doesn't make any difference to the encoded instruction. 3822 if (Opc != ARM::MRRC2) { 3823 Ops.push_back(getAL(CurDAG, dl)); 3824 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 3825 } 3826 3827 Ops.push_back(Chain); 3828 3829 // Writes to two registers. 3830 const EVT RetType[] = {MVT::i32, MVT::i32, MVT::Other}; 3831 3832 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, RetType, Ops)); 3833 return; 3834 } 3835 case Intrinsic::arm_ldaexd: 3836 case Intrinsic::arm_ldrexd: { 3837 SDLoc dl(N); 3838 SDValue Chain = N->getOperand(0); 3839 SDValue MemAddr = N->getOperand(2); 3840 bool isThumb = Subtarget->isThumb() && Subtarget->hasV8MBaselineOps(); 3841 3842 bool IsAcquire = IntNo == Intrinsic::arm_ldaexd; 3843 unsigned NewOpc = isThumb ? (IsAcquire ? ARM::t2LDAEXD : ARM::t2LDREXD) 3844 : (IsAcquire ? ARM::LDAEXD : ARM::LDREXD); 3845 3846 // arm_ldrexd returns a i64 value in {i32, i32} 3847 std::vector<EVT> ResTys; 3848 if (isThumb) { 3849 ResTys.push_back(MVT::i32); 3850 ResTys.push_back(MVT::i32); 3851 } else 3852 ResTys.push_back(MVT::Untyped); 3853 ResTys.push_back(MVT::Other); 3854 3855 // Place arguments in the right order. 3856 SDValue Ops[] = {MemAddr, getAL(CurDAG, dl), 3857 CurDAG->getRegister(0, MVT::i32), Chain}; 3858 SDNode *Ld = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops); 3859 // Transfer memoperands. 3860 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 3861 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp}); 3862 3863 // Remap uses. 3864 SDValue OutChain = isThumb ? SDValue(Ld, 2) : SDValue(Ld, 1); 3865 if (!SDValue(N, 0).use_empty()) { 3866 SDValue Result; 3867 if (isThumb) 3868 Result = SDValue(Ld, 0); 3869 else { 3870 SDValue SubRegIdx = 3871 CurDAG->getTargetConstant(ARM::gsub_0, dl, MVT::i32); 3872 SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 3873 dl, MVT::i32, SDValue(Ld, 0), SubRegIdx); 3874 Result = SDValue(ResNode,0); 3875 } 3876 ReplaceUses(SDValue(N, 0), Result); 3877 } 3878 if (!SDValue(N, 1).use_empty()) { 3879 SDValue Result; 3880 if (isThumb) 3881 Result = SDValue(Ld, 1); 3882 else { 3883 SDValue SubRegIdx = 3884 CurDAG->getTargetConstant(ARM::gsub_1, dl, MVT::i32); 3885 SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 3886 dl, MVT::i32, SDValue(Ld, 0), SubRegIdx); 3887 Result = SDValue(ResNode,0); 3888 } 3889 ReplaceUses(SDValue(N, 1), Result); 3890 } 3891 ReplaceUses(SDValue(N, 2), OutChain); 3892 CurDAG->RemoveDeadNode(N); 3893 return; 3894 } 3895 case Intrinsic::arm_stlexd: 3896 case Intrinsic::arm_strexd: { 3897 SDLoc dl(N); 3898 SDValue Chain = N->getOperand(0); 3899 SDValue Val0 = N->getOperand(2); 3900 SDValue Val1 = N->getOperand(3); 3901 SDValue MemAddr = N->getOperand(4); 3902 3903 // Store exclusive double return a i32 value which is the return status 3904 // of the issued store. 3905 const EVT ResTys[] = {MVT::i32, MVT::Other}; 3906 3907 bool isThumb = Subtarget->isThumb() && Subtarget->hasThumb2(); 3908 // Place arguments in the right order. 3909 SmallVector<SDValue, 7> Ops; 3910 if (isThumb) { 3911 Ops.push_back(Val0); 3912 Ops.push_back(Val1); 3913 } else 3914 // arm_strexd uses GPRPair. 3915 Ops.push_back(SDValue(createGPRPairNode(MVT::Untyped, Val0, Val1), 0)); 3916 Ops.push_back(MemAddr); 3917 Ops.push_back(getAL(CurDAG, dl)); 3918 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 3919 Ops.push_back(Chain); 3920 3921 bool IsRelease = IntNo == Intrinsic::arm_stlexd; 3922 unsigned NewOpc = isThumb ? (IsRelease ? ARM::t2STLEXD : ARM::t2STREXD) 3923 : (IsRelease ? ARM::STLEXD : ARM::STREXD); 3924 3925 SDNode *St = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops); 3926 // Transfer memoperands. 3927 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 3928 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp}); 3929 3930 ReplaceNode(N, St); 3931 return; 3932 } 3933 3934 case Intrinsic::arm_neon_vld1: { 3935 static const uint16_t DOpcodes[] = { ARM::VLD1d8, ARM::VLD1d16, 3936 ARM::VLD1d32, ARM::VLD1d64 }; 3937 static const uint16_t QOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16, 3938 ARM::VLD1q32, ARM::VLD1q64}; 3939 SelectVLD(N, false, 1, DOpcodes, QOpcodes, nullptr); 3940 return; 3941 } 3942 3943 case Intrinsic::arm_neon_vld1x2: { 3944 static const uint16_t DOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16, 3945 ARM::VLD1q32, ARM::VLD1q64 }; 3946 static const uint16_t QOpcodes[] = { ARM::VLD1d8QPseudo, 3947 ARM::VLD1d16QPseudo, 3948 ARM::VLD1d32QPseudo, 3949 ARM::VLD1d64QPseudo }; 3950 SelectVLD(N, false, 2, DOpcodes, QOpcodes, nullptr); 3951 return; 3952 } 3953 3954 case Intrinsic::arm_neon_vld1x3: { 3955 static const uint16_t DOpcodes[] = { ARM::VLD1d8TPseudo, 3956 ARM::VLD1d16TPseudo, 3957 ARM::VLD1d32TPseudo, 3958 ARM::VLD1d64TPseudo }; 3959 static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowTPseudo_UPD, 3960 ARM::VLD1q16LowTPseudo_UPD, 3961 ARM::VLD1q32LowTPseudo_UPD, 3962 ARM::VLD1q64LowTPseudo_UPD }; 3963 static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighTPseudo, 3964 ARM::VLD1q16HighTPseudo, 3965 ARM::VLD1q32HighTPseudo, 3966 ARM::VLD1q64HighTPseudo }; 3967 SelectVLD(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); 3968 return; 3969 } 3970 3971 case Intrinsic::arm_neon_vld1x4: { 3972 static const uint16_t DOpcodes[] = { ARM::VLD1d8QPseudo, 3973 ARM::VLD1d16QPseudo, 3974 ARM::VLD1d32QPseudo, 3975 ARM::VLD1d64QPseudo }; 3976 static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowQPseudo_UPD, 3977 ARM::VLD1q16LowQPseudo_UPD, 3978 ARM::VLD1q32LowQPseudo_UPD, 3979 ARM::VLD1q64LowQPseudo_UPD }; 3980 static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighQPseudo, 3981 ARM::VLD1q16HighQPseudo, 3982 ARM::VLD1q32HighQPseudo, 3983 ARM::VLD1q64HighQPseudo }; 3984 SelectVLD(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); 3985 return; 3986 } 3987 3988 case Intrinsic::arm_neon_vld2: { 3989 static const uint16_t DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16, 3990 ARM::VLD2d32, ARM::VLD1q64 }; 3991 static const uint16_t QOpcodes[] = { ARM::VLD2q8Pseudo, ARM::VLD2q16Pseudo, 3992 ARM::VLD2q32Pseudo }; 3993 SelectVLD(N, false, 2, DOpcodes, QOpcodes, nullptr); 3994 return; 3995 } 3996 3997 case Intrinsic::arm_neon_vld3: { 3998 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo, 3999 ARM::VLD3d16Pseudo, 4000 ARM::VLD3d32Pseudo, 4001 ARM::VLD1d64TPseudo }; 4002 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD, 4003 ARM::VLD3q16Pseudo_UPD, 4004 ARM::VLD3q32Pseudo_UPD }; 4005 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo, 4006 ARM::VLD3q16oddPseudo, 4007 ARM::VLD3q32oddPseudo }; 4008 SelectVLD(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); 4009 return; 4010 } 4011 4012 case Intrinsic::arm_neon_vld4: { 4013 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo, 4014 ARM::VLD4d16Pseudo, 4015 ARM::VLD4d32Pseudo, 4016 ARM::VLD1d64QPseudo }; 4017 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD, 4018 ARM::VLD4q16Pseudo_UPD, 4019 ARM::VLD4q32Pseudo_UPD }; 4020 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo, 4021 ARM::VLD4q16oddPseudo, 4022 ARM::VLD4q32oddPseudo }; 4023 SelectVLD(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); 4024 return; 4025 } 4026 4027 case Intrinsic::arm_neon_vld2dup: { 4028 static const uint16_t DOpcodes[] = { ARM::VLD2DUPd8, ARM::VLD2DUPd16, 4029 ARM::VLD2DUPd32, ARM::VLD1q64 }; 4030 static const uint16_t QOpcodes0[] = { ARM::VLD2DUPq8EvenPseudo, 4031 ARM::VLD2DUPq16EvenPseudo, 4032 ARM::VLD2DUPq32EvenPseudo }; 4033 static const uint16_t QOpcodes1[] = { ARM::VLD2DUPq8OddPseudo, 4034 ARM::VLD2DUPq16OddPseudo, 4035 ARM::VLD2DUPq32OddPseudo }; 4036 SelectVLDDup(N, /* IsIntrinsic= */ true, false, 2, 4037 DOpcodes, QOpcodes0, QOpcodes1); 4038 return; 4039 } 4040 4041 case Intrinsic::arm_neon_vld3dup: { 4042 static const uint16_t DOpcodes[] = { ARM::VLD3DUPd8Pseudo, 4043 ARM::VLD3DUPd16Pseudo, 4044 ARM::VLD3DUPd32Pseudo, 4045 ARM::VLD1d64TPseudo }; 4046 static const uint16_t QOpcodes0[] = { ARM::VLD3DUPq8EvenPseudo, 4047 ARM::VLD3DUPq16EvenPseudo, 4048 ARM::VLD3DUPq32EvenPseudo }; 4049 static const uint16_t QOpcodes1[] = { ARM::VLD3DUPq8OddPseudo, 4050 ARM::VLD3DUPq16OddPseudo, 4051 ARM::VLD3DUPq32OddPseudo }; 4052 SelectVLDDup(N, /* IsIntrinsic= */ true, false, 3, 4053 DOpcodes, QOpcodes0, QOpcodes1); 4054 return; 4055 } 4056 4057 case Intrinsic::arm_neon_vld4dup: { 4058 static const uint16_t DOpcodes[] = { ARM::VLD4DUPd8Pseudo, 4059 ARM::VLD4DUPd16Pseudo, 4060 ARM::VLD4DUPd32Pseudo, 4061 ARM::VLD1d64QPseudo }; 4062 static const uint16_t QOpcodes0[] = { ARM::VLD4DUPq8EvenPseudo, 4063 ARM::VLD4DUPq16EvenPseudo, 4064 ARM::VLD4DUPq32EvenPseudo }; 4065 static const uint16_t QOpcodes1[] = { ARM::VLD4DUPq8OddPseudo, 4066 ARM::VLD4DUPq16OddPseudo, 4067 ARM::VLD4DUPq32OddPseudo }; 4068 SelectVLDDup(N, /* IsIntrinsic= */ true, false, 4, 4069 DOpcodes, QOpcodes0, QOpcodes1); 4070 return; 4071 } 4072 4073 case Intrinsic::arm_neon_vld2lane: { 4074 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo, 4075 ARM::VLD2LNd16Pseudo, 4076 ARM::VLD2LNd32Pseudo }; 4077 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo, 4078 ARM::VLD2LNq32Pseudo }; 4079 SelectVLDSTLane(N, true, false, 2, DOpcodes, QOpcodes); 4080 return; 4081 } 4082 4083 case Intrinsic::arm_neon_vld3lane: { 4084 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo, 4085 ARM::VLD3LNd16Pseudo, 4086 ARM::VLD3LNd32Pseudo }; 4087 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo, 4088 ARM::VLD3LNq32Pseudo }; 4089 SelectVLDSTLane(N, true, false, 3, DOpcodes, QOpcodes); 4090 return; 4091 } 4092 4093 case Intrinsic::arm_neon_vld4lane: { 4094 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo, 4095 ARM::VLD4LNd16Pseudo, 4096 ARM::VLD4LNd32Pseudo }; 4097 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo, 4098 ARM::VLD4LNq32Pseudo }; 4099 SelectVLDSTLane(N, true, false, 4, DOpcodes, QOpcodes); 4100 return; 4101 } 4102 4103 case Intrinsic::arm_neon_vst1: { 4104 static const uint16_t DOpcodes[] = { ARM::VST1d8, ARM::VST1d16, 4105 ARM::VST1d32, ARM::VST1d64 }; 4106 static const uint16_t QOpcodes[] = { ARM::VST1q8, ARM::VST1q16, 4107 ARM::VST1q32, ARM::VST1q64 }; 4108 SelectVST(N, false, 1, DOpcodes, QOpcodes, nullptr); 4109 return; 4110 } 4111 4112 case Intrinsic::arm_neon_vst1x2: { 4113 static const uint16_t DOpcodes[] = { ARM::VST1q8, ARM::VST1q16, 4114 ARM::VST1q32, ARM::VST1q64 }; 4115 static const uint16_t QOpcodes[] = { ARM::VST1d8QPseudo, 4116 ARM::VST1d16QPseudo, 4117 ARM::VST1d32QPseudo, 4118 ARM::VST1d64QPseudo }; 4119 SelectVST(N, false, 2, DOpcodes, QOpcodes, nullptr); 4120 return; 4121 } 4122 4123 case Intrinsic::arm_neon_vst1x3: { 4124 static const uint16_t DOpcodes[] = { ARM::VST1d8TPseudo, 4125 ARM::VST1d16TPseudo, 4126 ARM::VST1d32TPseudo, 4127 ARM::VST1d64TPseudo }; 4128 static const uint16_t QOpcodes0[] = { ARM::VST1q8LowTPseudo_UPD, 4129 ARM::VST1q16LowTPseudo_UPD, 4130 ARM::VST1q32LowTPseudo_UPD, 4131 ARM::VST1q64LowTPseudo_UPD }; 4132 static const uint16_t QOpcodes1[] = { ARM::VST1q8HighTPseudo, 4133 ARM::VST1q16HighTPseudo, 4134 ARM::VST1q32HighTPseudo, 4135 ARM::VST1q64HighTPseudo }; 4136 SelectVST(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); 4137 return; 4138 } 4139 4140 case Intrinsic::arm_neon_vst1x4: { 4141 static const uint16_t DOpcodes[] = { ARM::VST1d8QPseudo, 4142 ARM::VST1d16QPseudo, 4143 ARM::VST1d32QPseudo, 4144 ARM::VST1d64QPseudo }; 4145 static const uint16_t QOpcodes0[] = { ARM::VST1q8LowQPseudo_UPD, 4146 ARM::VST1q16LowQPseudo_UPD, 4147 ARM::VST1q32LowQPseudo_UPD, 4148 ARM::VST1q64LowQPseudo_UPD }; 4149 static const uint16_t QOpcodes1[] = { ARM::VST1q8HighQPseudo, 4150 ARM::VST1q16HighQPseudo, 4151 ARM::VST1q32HighQPseudo, 4152 ARM::VST1q64HighQPseudo }; 4153 SelectVST(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); 4154 return; 4155 } 4156 4157 case Intrinsic::arm_neon_vst2: { 4158 static const uint16_t DOpcodes[] = { ARM::VST2d8, ARM::VST2d16, 4159 ARM::VST2d32, ARM::VST1q64 }; 4160 static const uint16_t QOpcodes[] = { ARM::VST2q8Pseudo, ARM::VST2q16Pseudo, 4161 ARM::VST2q32Pseudo }; 4162 SelectVST(N, false, 2, DOpcodes, QOpcodes, nullptr); 4163 return; 4164 } 4165 4166 case Intrinsic::arm_neon_vst3: { 4167 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo, 4168 ARM::VST3d16Pseudo, 4169 ARM::VST3d32Pseudo, 4170 ARM::VST1d64TPseudo }; 4171 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD, 4172 ARM::VST3q16Pseudo_UPD, 4173 ARM::VST3q32Pseudo_UPD }; 4174 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo, 4175 ARM::VST3q16oddPseudo, 4176 ARM::VST3q32oddPseudo }; 4177 SelectVST(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); 4178 return; 4179 } 4180 4181 case Intrinsic::arm_neon_vst4: { 4182 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo, 4183 ARM::VST4d16Pseudo, 4184 ARM::VST4d32Pseudo, 4185 ARM::VST1d64QPseudo }; 4186 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD, 4187 ARM::VST4q16Pseudo_UPD, 4188 ARM::VST4q32Pseudo_UPD }; 4189 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo, 4190 ARM::VST4q16oddPseudo, 4191 ARM::VST4q32oddPseudo }; 4192 SelectVST(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); 4193 return; 4194 } 4195 4196 case Intrinsic::arm_neon_vst2lane: { 4197 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo, 4198 ARM::VST2LNd16Pseudo, 4199 ARM::VST2LNd32Pseudo }; 4200 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo, 4201 ARM::VST2LNq32Pseudo }; 4202 SelectVLDSTLane(N, false, false, 2, DOpcodes, QOpcodes); 4203 return; 4204 } 4205 4206 case Intrinsic::arm_neon_vst3lane: { 4207 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo, 4208 ARM::VST3LNd16Pseudo, 4209 ARM::VST3LNd32Pseudo }; 4210 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo, 4211 ARM::VST3LNq32Pseudo }; 4212 SelectVLDSTLane(N, false, false, 3, DOpcodes, QOpcodes); 4213 return; 4214 } 4215 4216 case Intrinsic::arm_neon_vst4lane: { 4217 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo, 4218 ARM::VST4LNd16Pseudo, 4219 ARM::VST4LNd32Pseudo }; 4220 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo, 4221 ARM::VST4LNq32Pseudo }; 4222 SelectVLDSTLane(N, false, false, 4, DOpcodes, QOpcodes); 4223 return; 4224 } 4225 4226 case Intrinsic::arm_mve_vldr_gather_base_wb: 4227 case Intrinsic::arm_mve_vldr_gather_base_wb_predicated: { 4228 static const uint16_t Opcodes[] = {ARM::MVE_VLDRWU32_qi_pre, 4229 ARM::MVE_VLDRDU64_qi_pre}; 4230 SelectMVE_WB(N, Opcodes, 4231 IntNo == Intrinsic::arm_mve_vldr_gather_base_wb_predicated); 4232 return; 4233 } 4234 4235 case Intrinsic::arm_mve_vld2q: { 4236 static const uint16_t Opcodes8[] = {ARM::MVE_VLD20_8, ARM::MVE_VLD21_8}; 4237 static const uint16_t Opcodes16[] = {ARM::MVE_VLD20_16, 4238 ARM::MVE_VLD21_16}; 4239 static const uint16_t Opcodes32[] = {ARM::MVE_VLD20_32, 4240 ARM::MVE_VLD21_32}; 4241 static const uint16_t *const Opcodes[] = {Opcodes8, Opcodes16, Opcodes32}; 4242 SelectMVE_VLD(N, 2, Opcodes); 4243 return; 4244 } 4245 4246 case Intrinsic::arm_mve_vld4q: { 4247 static const uint16_t Opcodes8[] = {ARM::MVE_VLD40_8, ARM::MVE_VLD41_8, 4248 ARM::MVE_VLD42_8, ARM::MVE_VLD43_8}; 4249 static const uint16_t Opcodes16[] = {ARM::MVE_VLD40_16, ARM::MVE_VLD41_16, 4250 ARM::MVE_VLD42_16, 4251 ARM::MVE_VLD43_16}; 4252 static const uint16_t Opcodes32[] = {ARM::MVE_VLD40_32, ARM::MVE_VLD41_32, 4253 ARM::MVE_VLD42_32, 4254 ARM::MVE_VLD43_32}; 4255 static const uint16_t *const Opcodes[] = {Opcodes8, Opcodes16, Opcodes32}; 4256 SelectMVE_VLD(N, 4, Opcodes); 4257 return; 4258 } 4259 } 4260 break; 4261 } 4262 4263 case ISD::INTRINSIC_WO_CHAIN: { 4264 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 4265 switch (IntNo) { 4266 default: 4267 break; 4268 4269 case Intrinsic::arm_mve_urshrl: 4270 SelectMVE_LongShift(N, ARM::MVE_URSHRL, true); 4271 return; 4272 4273 case Intrinsic::arm_mve_vadc: 4274 case Intrinsic::arm_mve_vadc_predicated: 4275 SelectMVE_VADCSBC(N, ARM::MVE_VADC, ARM::MVE_VADCI, true, 4276 IntNo == Intrinsic::arm_mve_vadc_predicated); 4277 return; 4278 } 4279 break; 4280 } 4281 4282 case ISD::ATOMIC_CMP_SWAP: 4283 SelectCMP_SWAP(N); 4284 return; 4285 } 4286 4287 SelectCode(N); 4288 } 4289 4290 // Inspect a register string of the form 4291 // cp<coprocessor>:<opc1>:c<CRn>:c<CRm>:<opc2> (32bit) or 4292 // cp<coprocessor>:<opc1>:c<CRm> (64bit) inspect the fields of the string 4293 // and obtain the integer operands from them, adding these operands to the 4294 // provided vector. 4295 static void getIntOperandsFromRegisterString(StringRef RegString, 4296 SelectionDAG *CurDAG, 4297 const SDLoc &DL, 4298 std::vector<SDValue> &Ops) { 4299 SmallVector<StringRef, 5> Fields; 4300 RegString.split(Fields, ':'); 4301 4302 if (Fields.size() > 1) { 4303 bool AllIntFields = true; 4304 4305 for (StringRef Field : Fields) { 4306 // Need to trim out leading 'cp' characters and get the integer field. 4307 unsigned IntField; 4308 AllIntFields &= !Field.trim("CPcp").getAsInteger(10, IntField); 4309 Ops.push_back(CurDAG->getTargetConstant(IntField, DL, MVT::i32)); 4310 } 4311 4312 assert(AllIntFields && 4313 "Unexpected non-integer value in special register string."); 4314 } 4315 } 4316 4317 // Maps a Banked Register string to its mask value. The mask value returned is 4318 // for use in the MRSbanked / MSRbanked instruction nodes as the Banked Register 4319 // mask operand, which expresses which register is to be used, e.g. r8, and in 4320 // which mode it is to be used, e.g. usr. Returns -1 to signify that the string 4321 // was invalid. 4322 static inline int getBankedRegisterMask(StringRef RegString) { 4323 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegString.lower()); 4324 if (!TheReg) 4325 return -1; 4326 return TheReg->Encoding; 4327 } 4328 4329 // The flags here are common to those allowed for apsr in the A class cores and 4330 // those allowed for the special registers in the M class cores. Returns a 4331 // value representing which flags were present, -1 if invalid. 4332 static inline int getMClassFlagsMask(StringRef Flags) { 4333 return StringSwitch<int>(Flags) 4334 .Case("", 0x2) // no flags means nzcvq for psr registers, and 0x2 is 4335 // correct when flags are not permitted 4336 .Case("g", 0x1) 4337 .Case("nzcvq", 0x2) 4338 .Case("nzcvqg", 0x3) 4339 .Default(-1); 4340 } 4341 4342 // Maps MClass special registers string to its value for use in the 4343 // t2MRS_M/t2MSR_M instruction nodes as the SYSm value operand. 4344 // Returns -1 to signify that the string was invalid. 4345 static int getMClassRegisterMask(StringRef Reg, const ARMSubtarget *Subtarget) { 4346 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Reg); 4347 const FeatureBitset &FeatureBits = Subtarget->getFeatureBits(); 4348 if (!TheReg || !TheReg->hasRequiredFeatures(FeatureBits)) 4349 return -1; 4350 return (int)(TheReg->Encoding & 0xFFF); // SYSm value 4351 } 4352 4353 static int getARClassRegisterMask(StringRef Reg, StringRef Flags) { 4354 // The mask operand contains the special register (R Bit) in bit 4, whether 4355 // the register is spsr (R bit is 1) or one of cpsr/apsr (R bit is 0), and 4356 // bits 3-0 contains the fields to be accessed in the special register, set by 4357 // the flags provided with the register. 4358 int Mask = 0; 4359 if (Reg == "apsr") { 4360 // The flags permitted for apsr are the same flags that are allowed in 4361 // M class registers. We get the flag value and then shift the flags into 4362 // the correct place to combine with the mask. 4363 Mask = getMClassFlagsMask(Flags); 4364 if (Mask == -1) 4365 return -1; 4366 return Mask << 2; 4367 } 4368 4369 if (Reg != "cpsr" && Reg != "spsr") { 4370 return -1; 4371 } 4372 4373 // This is the same as if the flags were "fc" 4374 if (Flags.empty() || Flags == "all") 4375 return Mask | 0x9; 4376 4377 // Inspect the supplied flags string and set the bits in the mask for 4378 // the relevant and valid flags allowed for cpsr and spsr. 4379 for (char Flag : Flags) { 4380 int FlagVal; 4381 switch (Flag) { 4382 case 'c': 4383 FlagVal = 0x1; 4384 break; 4385 case 'x': 4386 FlagVal = 0x2; 4387 break; 4388 case 's': 4389 FlagVal = 0x4; 4390 break; 4391 case 'f': 4392 FlagVal = 0x8; 4393 break; 4394 default: 4395 FlagVal = 0; 4396 } 4397 4398 // This avoids allowing strings where the same flag bit appears twice. 4399 if (!FlagVal || (Mask & FlagVal)) 4400 return -1; 4401 Mask |= FlagVal; 4402 } 4403 4404 // If the register is spsr then we need to set the R bit. 4405 if (Reg == "spsr") 4406 Mask |= 0x10; 4407 4408 return Mask; 4409 } 4410 4411 // Lower the read_register intrinsic to ARM specific DAG nodes 4412 // using the supplied metadata string to select the instruction node to use 4413 // and the registers/masks to construct as operands for the node. 4414 bool ARMDAGToDAGISel::tryReadRegister(SDNode *N){ 4415 const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1)); 4416 const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0)); 4417 bool IsThumb2 = Subtarget->isThumb2(); 4418 SDLoc DL(N); 4419 4420 std::vector<SDValue> Ops; 4421 getIntOperandsFromRegisterString(RegString->getString(), CurDAG, DL, Ops); 4422 4423 if (!Ops.empty()) { 4424 // If the special register string was constructed of fields (as defined 4425 // in the ACLE) then need to lower to MRC node (32 bit) or 4426 // MRRC node(64 bit), we can make the distinction based on the number of 4427 // operands we have. 4428 unsigned Opcode; 4429 SmallVector<EVT, 3> ResTypes; 4430 if (Ops.size() == 5){ 4431 Opcode = IsThumb2 ? ARM::t2MRC : ARM::MRC; 4432 ResTypes.append({ MVT::i32, MVT::Other }); 4433 } else { 4434 assert(Ops.size() == 3 && 4435 "Invalid number of fields in special register string."); 4436 Opcode = IsThumb2 ? ARM::t2MRRC : ARM::MRRC; 4437 ResTypes.append({ MVT::i32, MVT::i32, MVT::Other }); 4438 } 4439 4440 Ops.push_back(getAL(CurDAG, DL)); 4441 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 4442 Ops.push_back(N->getOperand(0)); 4443 ReplaceNode(N, CurDAG->getMachineNode(Opcode, DL, ResTypes, Ops)); 4444 return true; 4445 } 4446 4447 std::string SpecialReg = RegString->getString().lower(); 4448 4449 int BankedReg = getBankedRegisterMask(SpecialReg); 4450 if (BankedReg != -1) { 4451 Ops = { CurDAG->getTargetConstant(BankedReg, DL, MVT::i32), 4452 getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 4453 N->getOperand(0) }; 4454 ReplaceNode( 4455 N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSbanked : ARM::MRSbanked, 4456 DL, MVT::i32, MVT::Other, Ops)); 4457 return true; 4458 } 4459 4460 // The VFP registers are read by creating SelectionDAG nodes with opcodes 4461 // corresponding to the register that is being read from. So we switch on the 4462 // string to find which opcode we need to use. 4463 unsigned Opcode = StringSwitch<unsigned>(SpecialReg) 4464 .Case("fpscr", ARM::VMRS) 4465 .Case("fpexc", ARM::VMRS_FPEXC) 4466 .Case("fpsid", ARM::VMRS_FPSID) 4467 .Case("mvfr0", ARM::VMRS_MVFR0) 4468 .Case("mvfr1", ARM::VMRS_MVFR1) 4469 .Case("mvfr2", ARM::VMRS_MVFR2) 4470 .Case("fpinst", ARM::VMRS_FPINST) 4471 .Case("fpinst2", ARM::VMRS_FPINST2) 4472 .Default(0); 4473 4474 // If an opcode was found then we can lower the read to a VFP instruction. 4475 if (Opcode) { 4476 if (!Subtarget->hasVFP2Base()) 4477 return false; 4478 if (Opcode == ARM::VMRS_MVFR2 && !Subtarget->hasFPARMv8Base()) 4479 return false; 4480 4481 Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 4482 N->getOperand(0) }; 4483 ReplaceNode(N, 4484 CurDAG->getMachineNode(Opcode, DL, MVT::i32, MVT::Other, Ops)); 4485 return true; 4486 } 4487 4488 // If the target is M Class then need to validate that the register string 4489 // is an acceptable value, so check that a mask can be constructed from the 4490 // string. 4491 if (Subtarget->isMClass()) { 4492 int SYSmValue = getMClassRegisterMask(SpecialReg, Subtarget); 4493 if (SYSmValue == -1) 4494 return false; 4495 4496 SDValue Ops[] = { CurDAG->getTargetConstant(SYSmValue, DL, MVT::i32), 4497 getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 4498 N->getOperand(0) }; 4499 ReplaceNode( 4500 N, CurDAG->getMachineNode(ARM::t2MRS_M, DL, MVT::i32, MVT::Other, Ops)); 4501 return true; 4502 } 4503 4504 // Here we know the target is not M Class so we need to check if it is one 4505 // of the remaining possible values which are apsr, cpsr or spsr. 4506 if (SpecialReg == "apsr" || SpecialReg == "cpsr") { 4507 Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 4508 N->getOperand(0) }; 4509 ReplaceNode(N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRS_AR : ARM::MRS, 4510 DL, MVT::i32, MVT::Other, Ops)); 4511 return true; 4512 } 4513 4514 if (SpecialReg == "spsr") { 4515 Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 4516 N->getOperand(0) }; 4517 ReplaceNode( 4518 N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSsys_AR : ARM::MRSsys, DL, 4519 MVT::i32, MVT::Other, Ops)); 4520 return true; 4521 } 4522 4523 return false; 4524 } 4525 4526 // Lower the write_register intrinsic to ARM specific DAG nodes 4527 // using the supplied metadata string to select the instruction node to use 4528 // and the registers/masks to use in the nodes 4529 bool ARMDAGToDAGISel::tryWriteRegister(SDNode *N){ 4530 const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1)); 4531 const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0)); 4532 bool IsThumb2 = Subtarget->isThumb2(); 4533 SDLoc DL(N); 4534 4535 std::vector<SDValue> Ops; 4536 getIntOperandsFromRegisterString(RegString->getString(), CurDAG, DL, Ops); 4537 4538 if (!Ops.empty()) { 4539 // If the special register string was constructed of fields (as defined 4540 // in the ACLE) then need to lower to MCR node (32 bit) or 4541 // MCRR node(64 bit), we can make the distinction based on the number of 4542 // operands we have. 4543 unsigned Opcode; 4544 if (Ops.size() == 5) { 4545 Opcode = IsThumb2 ? ARM::t2MCR : ARM::MCR; 4546 Ops.insert(Ops.begin()+2, N->getOperand(2)); 4547 } else { 4548 assert(Ops.size() == 3 && 4549 "Invalid number of fields in special register string."); 4550 Opcode = IsThumb2 ? ARM::t2MCRR : ARM::MCRR; 4551 SDValue WriteValue[] = { N->getOperand(2), N->getOperand(3) }; 4552 Ops.insert(Ops.begin()+2, WriteValue, WriteValue+2); 4553 } 4554 4555 Ops.push_back(getAL(CurDAG, DL)); 4556 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 4557 Ops.push_back(N->getOperand(0)); 4558 4559 ReplaceNode(N, CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops)); 4560 return true; 4561 } 4562 4563 std::string SpecialReg = RegString->getString().lower(); 4564 int BankedReg = getBankedRegisterMask(SpecialReg); 4565 if (BankedReg != -1) { 4566 Ops = { CurDAG->getTargetConstant(BankedReg, DL, MVT::i32), N->getOperand(2), 4567 getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 4568 N->getOperand(0) }; 4569 ReplaceNode( 4570 N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSRbanked : ARM::MSRbanked, 4571 DL, MVT::Other, Ops)); 4572 return true; 4573 } 4574 4575 // The VFP registers are written to by creating SelectionDAG nodes with 4576 // opcodes corresponding to the register that is being written. So we switch 4577 // on the string to find which opcode we need to use. 4578 unsigned Opcode = StringSwitch<unsigned>(SpecialReg) 4579 .Case("fpscr", ARM::VMSR) 4580 .Case("fpexc", ARM::VMSR_FPEXC) 4581 .Case("fpsid", ARM::VMSR_FPSID) 4582 .Case("fpinst", ARM::VMSR_FPINST) 4583 .Case("fpinst2", ARM::VMSR_FPINST2) 4584 .Default(0); 4585 4586 if (Opcode) { 4587 if (!Subtarget->hasVFP2Base()) 4588 return false; 4589 Ops = { N->getOperand(2), getAL(CurDAG, DL), 4590 CurDAG->getRegister(0, MVT::i32), N->getOperand(0) }; 4591 ReplaceNode(N, CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops)); 4592 return true; 4593 } 4594 4595 std::pair<StringRef, StringRef> Fields; 4596 Fields = StringRef(SpecialReg).rsplit('_'); 4597 std::string Reg = Fields.first.str(); 4598 StringRef Flags = Fields.second; 4599 4600 // If the target was M Class then need to validate the special register value 4601 // and retrieve the mask for use in the instruction node. 4602 if (Subtarget->isMClass()) { 4603 int SYSmValue = getMClassRegisterMask(SpecialReg, Subtarget); 4604 if (SYSmValue == -1) 4605 return false; 4606 4607 SDValue Ops[] = { CurDAG->getTargetConstant(SYSmValue, DL, MVT::i32), 4608 N->getOperand(2), getAL(CurDAG, DL), 4609 CurDAG->getRegister(0, MVT::i32), N->getOperand(0) }; 4610 ReplaceNode(N, CurDAG->getMachineNode(ARM::t2MSR_M, DL, MVT::Other, Ops)); 4611 return true; 4612 } 4613 4614 // We then check to see if a valid mask can be constructed for one of the 4615 // register string values permitted for the A and R class cores. These values 4616 // are apsr, spsr and cpsr; these are also valid on older cores. 4617 int Mask = getARClassRegisterMask(Reg, Flags); 4618 if (Mask != -1) { 4619 Ops = { CurDAG->getTargetConstant(Mask, DL, MVT::i32), N->getOperand(2), 4620 getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 4621 N->getOperand(0) }; 4622 ReplaceNode(N, CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSR_AR : ARM::MSR, 4623 DL, MVT::Other, Ops)); 4624 return true; 4625 } 4626 4627 return false; 4628 } 4629 4630 bool ARMDAGToDAGISel::tryInlineAsm(SDNode *N){ 4631 std::vector<SDValue> AsmNodeOperands; 4632 unsigned Flag, Kind; 4633 bool Changed = false; 4634 unsigned NumOps = N->getNumOperands(); 4635 4636 // Normally, i64 data is bounded to two arbitrary GRPs for "%r" constraint. 4637 // However, some instrstions (e.g. ldrexd/strexd in ARM mode) require 4638 // (even/even+1) GPRs and use %n and %Hn to refer to the individual regs 4639 // respectively. Since there is no constraint to explicitly specify a 4640 // reg pair, we use GPRPair reg class for "%r" for 64-bit data. For Thumb, 4641 // the 64-bit data may be referred by H, Q, R modifiers, so we still pack 4642 // them into a GPRPair. 4643 4644 SDLoc dl(N); 4645 SDValue Glue = N->getGluedNode() ? N->getOperand(NumOps-1) 4646 : SDValue(nullptr,0); 4647 4648 SmallVector<bool, 8> OpChanged; 4649 // Glue node will be appended late. 4650 for(unsigned i = 0, e = N->getGluedNode() ? NumOps - 1 : NumOps; i < e; ++i) { 4651 SDValue op = N->getOperand(i); 4652 AsmNodeOperands.push_back(op); 4653 4654 if (i < InlineAsm::Op_FirstOperand) 4655 continue; 4656 4657 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(i))) { 4658 Flag = C->getZExtValue(); 4659 Kind = InlineAsm::getKind(Flag); 4660 } 4661 else 4662 continue; 4663 4664 // Immediate operands to inline asm in the SelectionDAG are modeled with 4665 // two operands. The first is a constant of value InlineAsm::Kind_Imm, and 4666 // the second is a constant with the value of the immediate. If we get here 4667 // and we have a Kind_Imm, skip the next operand, and continue. 4668 if (Kind == InlineAsm::Kind_Imm) { 4669 SDValue op = N->getOperand(++i); 4670 AsmNodeOperands.push_back(op); 4671 continue; 4672 } 4673 4674 unsigned NumRegs = InlineAsm::getNumOperandRegisters(Flag); 4675 if (NumRegs) 4676 OpChanged.push_back(false); 4677 4678 unsigned DefIdx = 0; 4679 bool IsTiedToChangedOp = false; 4680 // If it's a use that is tied with a previous def, it has no 4681 // reg class constraint. 4682 if (Changed && InlineAsm::isUseOperandTiedToDef(Flag, DefIdx)) 4683 IsTiedToChangedOp = OpChanged[DefIdx]; 4684 4685 // Memory operands to inline asm in the SelectionDAG are modeled with two 4686 // operands: a constant of value InlineAsm::Kind_Mem followed by the input 4687 // operand. If we get here and we have a Kind_Mem, skip the next operand (so 4688 // it doesn't get misinterpreted), and continue. We do this here because 4689 // it's important to update the OpChanged array correctly before moving on. 4690 if (Kind == InlineAsm::Kind_Mem) { 4691 SDValue op = N->getOperand(++i); 4692 AsmNodeOperands.push_back(op); 4693 continue; 4694 } 4695 4696 if (Kind != InlineAsm::Kind_RegUse && Kind != InlineAsm::Kind_RegDef 4697 && Kind != InlineAsm::Kind_RegDefEarlyClobber) 4698 continue; 4699 4700 unsigned RC; 4701 bool HasRC = InlineAsm::hasRegClassConstraint(Flag, RC); 4702 if ((!IsTiedToChangedOp && (!HasRC || RC != ARM::GPRRegClassID)) 4703 || NumRegs != 2) 4704 continue; 4705 4706 assert((i+2 < NumOps) && "Invalid number of operands in inline asm"); 4707 SDValue V0 = N->getOperand(i+1); 4708 SDValue V1 = N->getOperand(i+2); 4709 unsigned Reg0 = cast<RegisterSDNode>(V0)->getReg(); 4710 unsigned Reg1 = cast<RegisterSDNode>(V1)->getReg(); 4711 SDValue PairedReg; 4712 MachineRegisterInfo &MRI = MF->getRegInfo(); 4713 4714 if (Kind == InlineAsm::Kind_RegDef || 4715 Kind == InlineAsm::Kind_RegDefEarlyClobber) { 4716 // Replace the two GPRs with 1 GPRPair and copy values from GPRPair to 4717 // the original GPRs. 4718 4719 Register GPVR = MRI.createVirtualRegister(&ARM::GPRPairRegClass); 4720 PairedReg = CurDAG->getRegister(GPVR, MVT::Untyped); 4721 SDValue Chain = SDValue(N,0); 4722 4723 SDNode *GU = N->getGluedUser(); 4724 SDValue RegCopy = CurDAG->getCopyFromReg(Chain, dl, GPVR, MVT::Untyped, 4725 Chain.getValue(1)); 4726 4727 // Extract values from a GPRPair reg and copy to the original GPR reg. 4728 SDValue Sub0 = CurDAG->getTargetExtractSubreg(ARM::gsub_0, dl, MVT::i32, 4729 RegCopy); 4730 SDValue Sub1 = CurDAG->getTargetExtractSubreg(ARM::gsub_1, dl, MVT::i32, 4731 RegCopy); 4732 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0, 4733 RegCopy.getValue(1)); 4734 SDValue T1 = CurDAG->getCopyToReg(Sub1, dl, Reg1, Sub1, T0.getValue(1)); 4735 4736 // Update the original glue user. 4737 std::vector<SDValue> Ops(GU->op_begin(), GU->op_end()-1); 4738 Ops.push_back(T1.getValue(1)); 4739 CurDAG->UpdateNodeOperands(GU, Ops); 4740 } 4741 else { 4742 // For Kind == InlineAsm::Kind_RegUse, we first copy two GPRs into a 4743 // GPRPair and then pass the GPRPair to the inline asm. 4744 SDValue Chain = AsmNodeOperands[InlineAsm::Op_InputChain]; 4745 4746 // As REG_SEQ doesn't take RegisterSDNode, we copy them first. 4747 SDValue T0 = CurDAG->getCopyFromReg(Chain, dl, Reg0, MVT::i32, 4748 Chain.getValue(1)); 4749 SDValue T1 = CurDAG->getCopyFromReg(Chain, dl, Reg1, MVT::i32, 4750 T0.getValue(1)); 4751 SDValue Pair = SDValue(createGPRPairNode(MVT::Untyped, T0, T1), 0); 4752 4753 // Copy REG_SEQ into a GPRPair-typed VR and replace the original two 4754 // i32 VRs of inline asm with it. 4755 Register GPVR = MRI.createVirtualRegister(&ARM::GPRPairRegClass); 4756 PairedReg = CurDAG->getRegister(GPVR, MVT::Untyped); 4757 Chain = CurDAG->getCopyToReg(T1, dl, GPVR, Pair, T1.getValue(1)); 4758 4759 AsmNodeOperands[InlineAsm::Op_InputChain] = Chain; 4760 Glue = Chain.getValue(1); 4761 } 4762 4763 Changed = true; 4764 4765 if(PairedReg.getNode()) { 4766 OpChanged[OpChanged.size() -1 ] = true; 4767 Flag = InlineAsm::getFlagWord(Kind, 1 /* RegNum*/); 4768 if (IsTiedToChangedOp) 4769 Flag = InlineAsm::getFlagWordForMatchingOp(Flag, DefIdx); 4770 else 4771 Flag = InlineAsm::getFlagWordForRegClass(Flag, ARM::GPRPairRegClassID); 4772 // Replace the current flag. 4773 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant( 4774 Flag, dl, MVT::i32); 4775 // Add the new register node and skip the original two GPRs. 4776 AsmNodeOperands.push_back(PairedReg); 4777 // Skip the next two GPRs. 4778 i += 2; 4779 } 4780 } 4781 4782 if (Glue.getNode()) 4783 AsmNodeOperands.push_back(Glue); 4784 if (!Changed) 4785 return false; 4786 4787 SDValue New = CurDAG->getNode(N->getOpcode(), SDLoc(N), 4788 CurDAG->getVTList(MVT::Other, MVT::Glue), AsmNodeOperands); 4789 New->setNodeId(-1); 4790 ReplaceNode(N, New.getNode()); 4791 return true; 4792 } 4793 4794 4795 bool ARMDAGToDAGISel:: 4796 SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 4797 std::vector<SDValue> &OutOps) { 4798 switch(ConstraintID) { 4799 default: 4800 llvm_unreachable("Unexpected asm memory constraint"); 4801 case InlineAsm::Constraint_i: 4802 // FIXME: It seems strange that 'i' is needed here since it's supposed to 4803 // be an immediate and not a memory constraint. 4804 LLVM_FALLTHROUGH; 4805 case InlineAsm::Constraint_m: 4806 case InlineAsm::Constraint_o: 4807 case InlineAsm::Constraint_Q: 4808 case InlineAsm::Constraint_Um: 4809 case InlineAsm::Constraint_Un: 4810 case InlineAsm::Constraint_Uq: 4811 case InlineAsm::Constraint_Us: 4812 case InlineAsm::Constraint_Ut: 4813 case InlineAsm::Constraint_Uv: 4814 case InlineAsm::Constraint_Uy: 4815 // Require the address to be in a register. That is safe for all ARM 4816 // variants and it is hard to do anything much smarter without knowing 4817 // how the operand is used. 4818 OutOps.push_back(Op); 4819 return false; 4820 } 4821 return true; 4822 } 4823 4824 /// createARMISelDag - This pass converts a legalized DAG into a 4825 /// ARM-specific DAG, ready for instruction scheduling. 4826 /// 4827 FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM, 4828 CodeGenOpt::Level OptLevel) { 4829 return new ARMDAGToDAGISel(TM, OptLevel); 4830 } 4831