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