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