1 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines an instruction selector for the ARM target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ARM.h" 15 #include "ARMBaseInstrInfo.h" 16 #include "ARMTargetMachine.h" 17 #include "MCTargetDesc/ARMAddressingModes.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/IR/CallingConv.h" 26 #include "llvm/IR/Constants.h" 27 #include "llvm/IR/DerivedTypes.h" 28 #include "llvm/IR/Function.h" 29 #include "llvm/IR/Intrinsics.h" 30 #include "llvm/IR/LLVMContext.h" 31 #include "llvm/Support/CommandLine.h" 32 #include "llvm/Support/Compiler.h" 33 #include "llvm/Support/Debug.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Target/TargetLowering.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 static cl::opt<bool> 48 CheckVMLxHazard("check-vmlx-hazard", cl::Hidden, 49 cl::desc("Check fp vmla / vmls hazard at isel time"), 50 cl::init(true)); 51 52 //===--------------------------------------------------------------------===// 53 /// ARMDAGToDAGISel - ARM specific code to select ARM machine 54 /// instructions for SelectionDAG operations. 55 /// 56 namespace { 57 58 enum AddrMode2Type { 59 AM2_BASE, // Simple AM2 (+-imm12) 60 AM2_SHOP // Shifter-op AM2 61 }; 62 63 class ARMDAGToDAGISel : public SelectionDAGISel { 64 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 65 /// make the right decision when generating code for different targets. 66 const ARMSubtarget *Subtarget; 67 68 public: 69 explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm, CodeGenOpt::Level OptLevel) 70 : SelectionDAGISel(tm, OptLevel) {} 71 72 bool runOnMachineFunction(MachineFunction &MF) override { 73 // Reset the subtarget each time through. 74 Subtarget = &MF.getSubtarget<ARMSubtarget>(); 75 SelectionDAGISel::runOnMachineFunction(MF); 76 return true; 77 } 78 79 const char *getPassName() const override { 80 return "ARM Instruction Selection"; 81 } 82 83 void PreprocessISelDAG() override; 84 85 /// getI32Imm - Return a target constant of type i32 with the specified 86 /// value. 87 inline SDValue getI32Imm(unsigned Imm, SDLoc dl) { 88 return CurDAG->getTargetConstant(Imm, dl, MVT::i32); 89 } 90 91 SDNode *Select(SDNode *N) override; 92 93 94 bool hasNoVMLxHazardUse(SDNode *N) const; 95 bool isShifterOpProfitable(const SDValue &Shift, 96 ARM_AM::ShiftOpc ShOpcVal, unsigned ShAmt); 97 bool SelectRegShifterOperand(SDValue N, SDValue &A, 98 SDValue &B, SDValue &C, 99 bool CheckProfitability = true); 100 bool SelectImmShifterOperand(SDValue N, SDValue &A, 101 SDValue &B, bool CheckProfitability = true); 102 bool SelectShiftRegShifterOperand(SDValue N, SDValue &A, 103 SDValue &B, SDValue &C) { 104 // Don't apply the profitability check 105 return SelectRegShifterOperand(N, A, B, C, false); 106 } 107 bool SelectShiftImmShifterOperand(SDValue N, SDValue &A, 108 SDValue &B) { 109 // Don't apply the profitability check 110 return SelectImmShifterOperand(N, A, B, false); 111 } 112 113 bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); 114 bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc); 115 116 AddrMode2Type SelectAddrMode2Worker(SDValue N, SDValue &Base, 117 SDValue &Offset, SDValue &Opc); 118 bool SelectAddrMode2Base(SDValue N, SDValue &Base, SDValue &Offset, 119 SDValue &Opc) { 120 return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_BASE; 121 } 122 123 bool SelectAddrMode2ShOp(SDValue N, SDValue &Base, SDValue &Offset, 124 SDValue &Opc) { 125 return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_SHOP; 126 } 127 128 bool SelectAddrMode2(SDValue N, SDValue &Base, SDValue &Offset, 129 SDValue &Opc) { 130 SelectAddrMode2Worker(N, Base, Offset, Opc); 131 // return SelectAddrMode2ShOp(N, Base, Offset, Opc); 132 // This always matches one way or another. 133 return true; 134 } 135 136 bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) { 137 const ConstantSDNode *CN = cast<ConstantSDNode>(N); 138 Pred = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(N), MVT::i32); 139 Reg = CurDAG->getRegister(ARM::CPSR, MVT::i32); 140 return true; 141 } 142 143 bool SelectAddrMode2OffsetReg(SDNode *Op, SDValue N, 144 SDValue &Offset, SDValue &Opc); 145 bool SelectAddrMode2OffsetImm(SDNode *Op, SDValue N, 146 SDValue &Offset, SDValue &Opc); 147 bool SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N, 148 SDValue &Offset, SDValue &Opc); 149 bool SelectAddrOffsetNone(SDValue N, SDValue &Base); 150 bool SelectAddrMode3(SDValue N, SDValue &Base, 151 SDValue &Offset, SDValue &Opc); 152 bool SelectAddrMode3Offset(SDNode *Op, SDValue N, 153 SDValue &Offset, SDValue &Opc); 154 bool SelectAddrMode5(SDValue N, SDValue &Base, 155 SDValue &Offset); 156 bool SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr,SDValue &Align); 157 bool SelectAddrMode6Offset(SDNode *Op, SDValue N, SDValue &Offset); 158 159 bool SelectAddrModePC(SDValue N, SDValue &Offset, SDValue &Label); 160 161 // Thumb Addressing Modes: 162 bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset); 163 bool SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, SDValue &Base, 164 SDValue &OffImm); 165 bool SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base, 166 SDValue &OffImm); 167 bool SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base, 168 SDValue &OffImm); 169 bool SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base, 170 SDValue &OffImm); 171 bool SelectThumbAddrModeSP(SDValue N, SDValue &Base, SDValue &OffImm); 172 173 // Thumb 2 Addressing Modes: 174 bool SelectT2AddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); 175 bool SelectT2AddrModeImm8(SDValue N, SDValue &Base, 176 SDValue &OffImm); 177 bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 178 SDValue &OffImm); 179 bool SelectT2AddrModeSoReg(SDValue N, SDValue &Base, 180 SDValue &OffReg, SDValue &ShImm); 181 bool SelectT2AddrModeExclusive(SDValue N, SDValue &Base, SDValue &OffImm); 182 183 inline bool is_so_imm(unsigned Imm) const { 184 return ARM_AM::getSOImmVal(Imm) != -1; 185 } 186 187 inline bool is_so_imm_not(unsigned Imm) const { 188 return ARM_AM::getSOImmVal(~Imm) != -1; 189 } 190 191 inline bool is_t2_so_imm(unsigned Imm) const { 192 return ARM_AM::getT2SOImmVal(Imm) != -1; 193 } 194 195 inline bool is_t2_so_imm_not(unsigned Imm) const { 196 return ARM_AM::getT2SOImmVal(~Imm) != -1; 197 } 198 199 // Include the pieces autogenerated from the target description. 200 #include "ARMGenDAGISel.inc" 201 202 private: 203 /// SelectARMIndexedLoad - Indexed (pre/post inc/dec) load matching code for 204 /// ARM. 205 SDNode *SelectARMIndexedLoad(SDNode *N); 206 SDNode *SelectT2IndexedLoad(SDNode *N); 207 208 /// SelectVLD - Select NEON load intrinsics. NumVecs should be 209 /// 1, 2, 3 or 4. The opcode arrays specify the instructions used for 210 /// loads of D registers and even subregs and odd subregs of Q registers. 211 /// For NumVecs <= 2, QOpcodes1 is not used. 212 SDNode *SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs, 213 const uint16_t *DOpcodes, 214 const uint16_t *QOpcodes0, const uint16_t *QOpcodes1); 215 216 /// SelectVST - Select NEON store intrinsics. NumVecs should 217 /// be 1, 2, 3 or 4. The opcode arrays specify the instructions used for 218 /// stores of D registers and even subregs and odd subregs of Q registers. 219 /// For NumVecs <= 2, QOpcodes1 is not used. 220 SDNode *SelectVST(SDNode *N, bool isUpdating, unsigned NumVecs, 221 const uint16_t *DOpcodes, 222 const uint16_t *QOpcodes0, const uint16_t *QOpcodes1); 223 224 /// SelectVLDSTLane - Select NEON load/store lane intrinsics. NumVecs should 225 /// be 2, 3 or 4. The opcode arrays specify the instructions used for 226 /// load/store of D registers and Q registers. 227 SDNode *SelectVLDSTLane(SDNode *N, bool IsLoad, 228 bool isUpdating, unsigned NumVecs, 229 const uint16_t *DOpcodes, const uint16_t *QOpcodes); 230 231 /// SelectVLDDup - Select NEON load-duplicate intrinsics. NumVecs 232 /// should be 2, 3 or 4. The opcode array specifies the instructions used 233 /// for loading D registers. (Q registers are not supported.) 234 SDNode *SelectVLDDup(SDNode *N, bool isUpdating, unsigned NumVecs, 235 const uint16_t *Opcodes); 236 237 /// SelectVTBL - Select NEON VTBL and VTBX intrinsics. NumVecs should be 2, 238 /// 3 or 4. These are custom-selected so that a REG_SEQUENCE can be 239 /// generated to force the table registers to be consecutive. 240 SDNode *SelectVTBL(SDNode *N, bool IsExt, unsigned NumVecs, unsigned Opc); 241 242 /// SelectV6T2BitfieldExtractOp - Select SBFX/UBFX instructions for ARM. 243 SDNode *SelectV6T2BitfieldExtractOp(SDNode *N, bool isSigned); 244 245 // Select special operations if node forms integer ABS pattern 246 SDNode *SelectABSOp(SDNode *N); 247 248 SDNode *SelectReadRegister(SDNode *N); 249 SDNode *SelectWriteRegister(SDNode *N); 250 251 SDNode *SelectInlineAsm(SDNode *N); 252 253 SDNode *SelectConcatVector(SDNode *N); 254 255 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 256 /// inline asm expressions. 257 bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 258 std::vector<SDValue> &OutOps) override; 259 260 // Form pairs of consecutive R, S, D, or Q registers. 261 SDNode *createGPRPairNode(EVT VT, SDValue V0, SDValue V1); 262 SDNode *createSRegPairNode(EVT VT, SDValue V0, SDValue V1); 263 SDNode *createDRegPairNode(EVT VT, SDValue V0, SDValue V1); 264 SDNode *createQRegPairNode(EVT VT, SDValue V0, SDValue V1); 265 266 // Form sequences of 4 consecutive S, D, or Q registers. 267 SDNode *createQuadSRegsNode(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3); 268 SDNode *createQuadDRegsNode(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3); 269 SDNode *createQuadQRegsNode(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3); 270 271 // Get the alignment operand for a NEON VLD or VST instruction. 272 SDValue GetVLDSTAlign(SDValue Align, SDLoc dl, unsigned NumVecs, 273 bool is64BitVector); 274 275 /// Returns the number of instructions required to materialize the given 276 /// constant in a register, or 3 if a literal pool load is needed. 277 unsigned ConstantMaterializationCost(unsigned Val) const; 278 279 /// Checks if N is a multiplication by a constant where we can extract out a 280 /// power of two from the constant so that it can be used in a shift, but only 281 /// if it simplifies the materialization of the constant. Returns true if it 282 /// is, and assigns to PowerOfTwo the power of two that should be extracted 283 /// out and to NewMulConst the new constant to be multiplied by. 284 bool canExtractShiftFromMul(const SDValue &N, unsigned MaxShift, 285 unsigned &PowerOfTwo, SDValue &NewMulConst) const; 286 287 /// Replace N with M in CurDAG, in a way that also ensures that M gets 288 /// selected when N would have been selected. 289 void replaceDAGValue(const SDValue &N, SDValue M); 290 }; 291 } 292 293 /// isInt32Immediate - This method tests to see if the node is a 32-bit constant 294 /// operand. If so Imm will receive the 32-bit value. 295 static bool isInt32Immediate(SDNode *N, unsigned &Imm) { 296 if (N->getOpcode() == ISD::Constant && N->getValueType(0) == MVT::i32) { 297 Imm = cast<ConstantSDNode>(N)->getZExtValue(); 298 return true; 299 } 300 return false; 301 } 302 303 // isInt32Immediate - This method tests to see if a constant operand. 304 // If so Imm will receive the 32 bit value. 305 static bool isInt32Immediate(SDValue N, unsigned &Imm) { 306 return isInt32Immediate(N.getNode(), Imm); 307 } 308 309 // isOpcWithIntImmediate - This method tests to see if the node is a specific 310 // opcode and that it has a immediate integer right operand. 311 // If so Imm will receive the 32 bit value. 312 static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) { 313 return N->getOpcode() == Opc && 314 isInt32Immediate(N->getOperand(1).getNode(), Imm); 315 } 316 317 /// \brief Check whether a particular node is a constant value representable as 318 /// (N * Scale) where (N in [\p RangeMin, \p RangeMax). 319 /// 320 /// \param ScaledConstant [out] - On success, the pre-scaled constant value. 321 static bool isScaledConstantInRange(SDValue Node, int Scale, 322 int RangeMin, int RangeMax, 323 int &ScaledConstant) { 324 assert(Scale > 0 && "Invalid scale!"); 325 326 // Check that this is a constant. 327 const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Node); 328 if (!C) 329 return false; 330 331 ScaledConstant = (int) C->getZExtValue(); 332 if ((ScaledConstant % Scale) != 0) 333 return false; 334 335 ScaledConstant /= Scale; 336 return ScaledConstant >= RangeMin && ScaledConstant < RangeMax; 337 } 338 339 void ARMDAGToDAGISel::PreprocessISelDAG() { 340 if (!Subtarget->hasV6T2Ops()) 341 return; 342 343 bool isThumb2 = Subtarget->isThumb(); 344 for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(), 345 E = CurDAG->allnodes_end(); I != E; ) { 346 SDNode *N = &*I++; // Preincrement iterator to avoid invalidation issues. 347 348 if (N->getOpcode() != ISD::ADD) 349 continue; 350 351 // Look for (add X1, (and (srl X2, c1), c2)) where c2 is constant with 352 // leading zeros, followed by consecutive set bits, followed by 1 or 2 353 // trailing zeros, e.g. 1020. 354 // Transform the expression to 355 // (add X1, (shl (and (srl X2, c1), (c2>>tz)), tz)) where tz is the number 356 // of trailing zeros of c2. The left shift would be folded as an shifter 357 // operand of 'add' and the 'and' and 'srl' would become a bits extraction 358 // node (UBFX). 359 360 SDValue N0 = N->getOperand(0); 361 SDValue N1 = N->getOperand(1); 362 unsigned And_imm = 0; 363 if (!isOpcWithIntImmediate(N1.getNode(), ISD::AND, And_imm)) { 364 if (isOpcWithIntImmediate(N0.getNode(), ISD::AND, And_imm)) 365 std::swap(N0, N1); 366 } 367 if (!And_imm) 368 continue; 369 370 // Check if the AND mask is an immediate of the form: 000.....1111111100 371 unsigned TZ = countTrailingZeros(And_imm); 372 if (TZ != 1 && TZ != 2) 373 // Be conservative here. Shifter operands aren't always free. e.g. On 374 // Swift, left shifter operand of 1 / 2 for free but others are not. 375 // e.g. 376 // ubfx r3, r1, #16, #8 377 // ldr.w r3, [r0, r3, lsl #2] 378 // vs. 379 // mov.w r9, #1020 380 // and.w r2, r9, r1, lsr #14 381 // ldr r2, [r0, r2] 382 continue; 383 And_imm >>= TZ; 384 if (And_imm & (And_imm + 1)) 385 continue; 386 387 // Look for (and (srl X, c1), c2). 388 SDValue Srl = N1.getOperand(0); 389 unsigned Srl_imm = 0; 390 if (!isOpcWithIntImmediate(Srl.getNode(), ISD::SRL, Srl_imm) || 391 (Srl_imm <= 2)) 392 continue; 393 394 // Make sure first operand is not a shifter operand which would prevent 395 // folding of the left shift. 396 SDValue CPTmp0; 397 SDValue CPTmp1; 398 SDValue CPTmp2; 399 if (isThumb2) { 400 if (SelectImmShifterOperand(N0, CPTmp0, CPTmp1)) 401 continue; 402 } else { 403 if (SelectImmShifterOperand(N0, CPTmp0, CPTmp1) || 404 SelectRegShifterOperand(N0, CPTmp0, CPTmp1, CPTmp2)) 405 continue; 406 } 407 408 // Now make the transformation. 409 Srl = CurDAG->getNode(ISD::SRL, SDLoc(Srl), MVT::i32, 410 Srl.getOperand(0), 411 CurDAG->getConstant(Srl_imm + TZ, SDLoc(Srl), 412 MVT::i32)); 413 N1 = CurDAG->getNode(ISD::AND, SDLoc(N1), MVT::i32, 414 Srl, 415 CurDAG->getConstant(And_imm, SDLoc(Srl), MVT::i32)); 416 N1 = CurDAG->getNode(ISD::SHL, SDLoc(N1), MVT::i32, 417 N1, CurDAG->getConstant(TZ, SDLoc(Srl), MVT::i32)); 418 CurDAG->UpdateNodeOperands(N, N0, N1); 419 } 420 } 421 422 /// hasNoVMLxHazardUse - Return true if it's desirable to select a FP MLA / MLS 423 /// node. VFP / NEON fp VMLA / VMLS instructions have special RAW hazards (at 424 /// least on current ARM implementations) which should be avoidded. 425 bool ARMDAGToDAGISel::hasNoVMLxHazardUse(SDNode *N) const { 426 if (OptLevel == CodeGenOpt::None) 427 return true; 428 429 if (!CheckVMLxHazard) 430 return true; 431 432 if (!Subtarget->isCortexA7() && !Subtarget->isCortexA8() && 433 !Subtarget->isCortexA9() && !Subtarget->isSwift()) 434 return true; 435 436 if (!N->hasOneUse()) 437 return false; 438 439 SDNode *Use = *N->use_begin(); 440 if (Use->getOpcode() == ISD::CopyToReg) 441 return true; 442 if (Use->isMachineOpcode()) { 443 const ARMBaseInstrInfo *TII = static_cast<const ARMBaseInstrInfo *>( 444 CurDAG->getSubtarget().getInstrInfo()); 445 446 const MCInstrDesc &MCID = TII->get(Use->getMachineOpcode()); 447 if (MCID.mayStore()) 448 return true; 449 unsigned Opcode = MCID.getOpcode(); 450 if (Opcode == ARM::VMOVRS || Opcode == ARM::VMOVRRD) 451 return true; 452 // vmlx feeding into another vmlx. We actually want to unfold 453 // the use later in the MLxExpansion pass. e.g. 454 // vmla 455 // vmla (stall 8 cycles) 456 // 457 // vmul (5 cycles) 458 // vadd (5 cycles) 459 // vmla 460 // This adds up to about 18 - 19 cycles. 461 // 462 // vmla 463 // vmul (stall 4 cycles) 464 // vadd adds up to about 14 cycles. 465 return TII->isFpMLxInstruction(Opcode); 466 } 467 468 return false; 469 } 470 471 bool ARMDAGToDAGISel::isShifterOpProfitable(const SDValue &Shift, 472 ARM_AM::ShiftOpc ShOpcVal, 473 unsigned ShAmt) { 474 if (!Subtarget->isLikeA9() && !Subtarget->isSwift()) 475 return true; 476 if (Shift.hasOneUse()) 477 return true; 478 // R << 2 is free. 479 return ShOpcVal == ARM_AM::lsl && 480 (ShAmt == 2 || (Subtarget->isSwift() && ShAmt == 1)); 481 } 482 483 unsigned ARMDAGToDAGISel::ConstantMaterializationCost(unsigned Val) const { 484 if (Subtarget->isThumb()) { 485 if (Val <= 255) return 1; // MOV 486 if (Subtarget->hasV6T2Ops() && Val <= 0xffff) return 1; // MOVW 487 if (~Val <= 255) return 2; // MOV + MVN 488 if (ARM_AM::isThumbImmShiftedVal(Val)) return 2; // MOV + LSL 489 } else { 490 if (ARM_AM::getSOImmVal(Val) != -1) return 1; // MOV 491 if (ARM_AM::getSOImmVal(~Val) != -1) return 1; // MVN 492 if (Subtarget->hasV6T2Ops() && Val <= 0xffff) return 1; // MOVW 493 if (ARM_AM::isSOImmTwoPartVal(Val)) return 2; // two instrs 494 } 495 if (Subtarget->useMovt(*MF)) return 2; // MOVW + MOVT 496 return 3; // Literal pool load 497 } 498 499 bool ARMDAGToDAGISel::canExtractShiftFromMul(const SDValue &N, 500 unsigned MaxShift, 501 unsigned &PowerOfTwo, 502 SDValue &NewMulConst) const { 503 assert(N.getOpcode() == ISD::MUL); 504 assert(MaxShift > 0); 505 506 // If the multiply is used in more than one place then changing the constant 507 // will make other uses incorrect, so don't. 508 if (!N.hasOneUse()) return false; 509 // Check if the multiply is by a constant 510 ConstantSDNode *MulConst = dyn_cast<ConstantSDNode>(N.getOperand(1)); 511 if (!MulConst) return false; 512 // If the constant is used in more than one place then modifying it will mean 513 // we need to materialize two constants instead of one, which is a bad idea. 514 if (!MulConst->hasOneUse()) return false; 515 unsigned MulConstVal = MulConst->getZExtValue(); 516 if (MulConstVal == 0) return false; 517 518 // Find the largest power of 2 that MulConstVal is a multiple of 519 PowerOfTwo = MaxShift; 520 while ((MulConstVal % (1 << PowerOfTwo)) != 0) { 521 --PowerOfTwo; 522 if (PowerOfTwo == 0) return false; 523 } 524 525 // Only optimise if the new cost is better 526 unsigned NewMulConstVal = MulConstVal / (1 << PowerOfTwo); 527 NewMulConst = CurDAG->getConstant(NewMulConstVal, SDLoc(N), MVT::i32); 528 unsigned OldCost = ConstantMaterializationCost(MulConstVal); 529 unsigned NewCost = ConstantMaterializationCost(NewMulConstVal); 530 return NewCost < OldCost; 531 } 532 533 void ARMDAGToDAGISel::replaceDAGValue(const SDValue &N, SDValue M) { 534 CurDAG->RepositionNode(N.getNode()->getIterator(), M.getNode()); 535 CurDAG->ReplaceAllUsesWith(N, M); 536 } 537 538 bool ARMDAGToDAGISel::SelectImmShifterOperand(SDValue N, 539 SDValue &BaseReg, 540 SDValue &Opc, 541 bool CheckProfitability) { 542 if (DisableShifterOp) 543 return false; 544 545 // If N is a multiply-by-constant and it's profitable to extract a shift and 546 // use it in a shifted operand do so. 547 if (N.getOpcode() == ISD::MUL) { 548 unsigned PowerOfTwo = 0; 549 SDValue NewMulConst; 550 if (canExtractShiftFromMul(N, 31, PowerOfTwo, NewMulConst)) { 551 BaseReg = SDValue(Select(CurDAG->getNode(ISD::MUL, SDLoc(N), MVT::i32, 552 N.getOperand(0), NewMulConst) 553 .getNode()), 554 0); 555 replaceDAGValue(N.getOperand(1), NewMulConst); 556 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ARM_AM::lsl, 557 PowerOfTwo), 558 SDLoc(N), MVT::i32); 559 return true; 560 } 561 } 562 563 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); 564 565 // Don't match base register only case. That is matched to a separate 566 // lower complexity pattern with explicit register operand. 567 if (ShOpcVal == ARM_AM::no_shift) return false; 568 569 BaseReg = N.getOperand(0); 570 unsigned ShImmVal = 0; 571 ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1)); 572 if (!RHS) return false; 573 ShImmVal = RHS->getZExtValue() & 31; 574 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 575 SDLoc(N), MVT::i32); 576 return true; 577 } 578 579 bool ARMDAGToDAGISel::SelectRegShifterOperand(SDValue N, 580 SDValue &BaseReg, 581 SDValue &ShReg, 582 SDValue &Opc, 583 bool CheckProfitability) { 584 if (DisableShifterOp) 585 return false; 586 587 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); 588 589 // Don't match base register only case. That is matched to a separate 590 // lower complexity pattern with explicit register operand. 591 if (ShOpcVal == ARM_AM::no_shift) return false; 592 593 BaseReg = N.getOperand(0); 594 unsigned ShImmVal = 0; 595 ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1)); 596 if (RHS) return false; 597 598 ShReg = N.getOperand(1); 599 if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal)) 600 return false; 601 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 602 SDLoc(N), MVT::i32); 603 return true; 604 } 605 606 607 bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N, 608 SDValue &Base, 609 SDValue &OffImm) { 610 // Match simple R + imm12 operands. 611 612 // Base only. 613 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && 614 !CurDAG->isBaseWithConstantOffset(N)) { 615 if (N.getOpcode() == ISD::FrameIndex) { 616 // Match frame index. 617 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 618 Base = CurDAG->getTargetFrameIndex( 619 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 620 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 621 return true; 622 } 623 624 if (N.getOpcode() == ARMISD::Wrapper && 625 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress && 626 N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol && 627 N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) { 628 Base = N.getOperand(0); 629 } else 630 Base = N; 631 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 632 return true; 633 } 634 635 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 636 int RHSC = (int)RHS->getSExtValue(); 637 if (N.getOpcode() == ISD::SUB) 638 RHSC = -RHSC; 639 640 if (RHSC > -0x1000 && RHSC < 0x1000) { // 12 bits 641 Base = N.getOperand(0); 642 if (Base.getOpcode() == ISD::FrameIndex) { 643 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 644 Base = CurDAG->getTargetFrameIndex( 645 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 646 } 647 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 648 return true; 649 } 650 } 651 652 // Base only. 653 Base = N; 654 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 655 return true; 656 } 657 658 659 660 bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, 661 SDValue &Opc) { 662 if (N.getOpcode() == ISD::MUL && 663 ((!Subtarget->isLikeA9() && !Subtarget->isSwift()) || N.hasOneUse())) { 664 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 665 // X * [3,5,9] -> X + X * [2,4,8] etc. 666 int RHSC = (int)RHS->getZExtValue(); 667 if (RHSC & 1) { 668 RHSC = RHSC & ~1; 669 ARM_AM::AddrOpc AddSub = ARM_AM::add; 670 if (RHSC < 0) { 671 AddSub = ARM_AM::sub; 672 RHSC = - RHSC; 673 } 674 if (isPowerOf2_32(RHSC)) { 675 unsigned ShAmt = Log2_32(RHSC); 676 Base = Offset = N.getOperand(0); 677 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, 678 ARM_AM::lsl), 679 SDLoc(N), MVT::i32); 680 return true; 681 } 682 } 683 } 684 } 685 686 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && 687 // ISD::OR that is equivalent to an ISD::ADD. 688 !CurDAG->isBaseWithConstantOffset(N)) 689 return false; 690 691 // Leave simple R +/- imm12 operands for LDRi12 692 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) { 693 int RHSC; 694 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/1, 695 -0x1000+1, 0x1000, RHSC)) // 12 bits. 696 return false; 697 } 698 699 // Otherwise this is R +/- [possibly shifted] R. 700 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::SUB ? ARM_AM::sub:ARM_AM::add; 701 ARM_AM::ShiftOpc ShOpcVal = 702 ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode()); 703 unsigned ShAmt = 0; 704 705 Base = N.getOperand(0); 706 Offset = N.getOperand(1); 707 708 if (ShOpcVal != ARM_AM::no_shift) { 709 // Check to see if the RHS of the shift is a constant, if not, we can't fold 710 // it. 711 if (ConstantSDNode *Sh = 712 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) { 713 ShAmt = Sh->getZExtValue(); 714 if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt)) 715 Offset = N.getOperand(1).getOperand(0); 716 else { 717 ShAmt = 0; 718 ShOpcVal = ARM_AM::no_shift; 719 } 720 } else { 721 ShOpcVal = ARM_AM::no_shift; 722 } 723 } 724 725 // Try matching (R shl C) + (R). 726 if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift && 727 !(Subtarget->isLikeA9() || Subtarget->isSwift() || 728 N.getOperand(0).hasOneUse())) { 729 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode()); 730 if (ShOpcVal != ARM_AM::no_shift) { 731 // Check to see if the RHS of the shift is a constant, if not, we can't 732 // fold it. 733 if (ConstantSDNode *Sh = 734 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) { 735 ShAmt = Sh->getZExtValue(); 736 if (isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt)) { 737 Offset = N.getOperand(0).getOperand(0); 738 Base = N.getOperand(1); 739 } else { 740 ShAmt = 0; 741 ShOpcVal = ARM_AM::no_shift; 742 } 743 } else { 744 ShOpcVal = ARM_AM::no_shift; 745 } 746 } 747 } 748 749 // If Offset is a multiply-by-constant and it's profitable to extract a shift 750 // and use it in a shifted operand do so. 751 if (Offset.getOpcode() == ISD::MUL && N.hasOneUse()) { 752 unsigned PowerOfTwo = 0; 753 SDValue NewMulConst; 754 if (canExtractShiftFromMul(Offset, 31, PowerOfTwo, NewMulConst)) { 755 replaceDAGValue(Offset.getOperand(1), NewMulConst); 756 ShAmt = PowerOfTwo; 757 ShOpcVal = ARM_AM::lsl; 758 } 759 } 760 761 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 762 SDLoc(N), MVT::i32); 763 return true; 764 } 765 766 767 //----- 768 769 AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N, 770 SDValue &Base, 771 SDValue &Offset, 772 SDValue &Opc) { 773 if (N.getOpcode() == ISD::MUL && 774 (!(Subtarget->isLikeA9() || Subtarget->isSwift()) || N.hasOneUse())) { 775 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 776 // X * [3,5,9] -> X + X * [2,4,8] etc. 777 int RHSC = (int)RHS->getZExtValue(); 778 if (RHSC & 1) { 779 RHSC = RHSC & ~1; 780 ARM_AM::AddrOpc AddSub = ARM_AM::add; 781 if (RHSC < 0) { 782 AddSub = ARM_AM::sub; 783 RHSC = - RHSC; 784 } 785 if (isPowerOf2_32(RHSC)) { 786 unsigned ShAmt = Log2_32(RHSC); 787 Base = Offset = N.getOperand(0); 788 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, 789 ARM_AM::lsl), 790 SDLoc(N), MVT::i32); 791 return AM2_SHOP; 792 } 793 } 794 } 795 } 796 797 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && 798 // ISD::OR that is equivalent to an ADD. 799 !CurDAG->isBaseWithConstantOffset(N)) { 800 Base = N; 801 if (N.getOpcode() == ISD::FrameIndex) { 802 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 803 Base = CurDAG->getTargetFrameIndex( 804 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 805 } else if (N.getOpcode() == ARMISD::Wrapper && 806 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress && 807 N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol && 808 N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) { 809 Base = N.getOperand(0); 810 } 811 Offset = CurDAG->getRegister(0, MVT::i32); 812 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, 813 ARM_AM::no_shift), 814 SDLoc(N), MVT::i32); 815 return AM2_BASE; 816 } 817 818 // Match simple R +/- imm12 operands. 819 if (N.getOpcode() != ISD::SUB) { 820 int RHSC; 821 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/1, 822 -0x1000+1, 0x1000, RHSC)) { // 12 bits. 823 Base = N.getOperand(0); 824 if (Base.getOpcode() == ISD::FrameIndex) { 825 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 826 Base = CurDAG->getTargetFrameIndex( 827 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 828 } 829 Offset = CurDAG->getRegister(0, MVT::i32); 830 831 ARM_AM::AddrOpc AddSub = ARM_AM::add; 832 if (RHSC < 0) { 833 AddSub = ARM_AM::sub; 834 RHSC = - RHSC; 835 } 836 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC, 837 ARM_AM::no_shift), 838 SDLoc(N), MVT::i32); 839 return AM2_BASE; 840 } 841 } 842 843 if ((Subtarget->isLikeA9() || Subtarget->isSwift()) && !N.hasOneUse()) { 844 // Compute R +/- (R << N) and reuse it. 845 Base = N; 846 Offset = CurDAG->getRegister(0, MVT::i32); 847 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, 848 ARM_AM::no_shift), 849 SDLoc(N), MVT::i32); 850 return AM2_BASE; 851 } 852 853 // Otherwise this is R +/- [possibly shifted] R. 854 ARM_AM::AddrOpc AddSub = N.getOpcode() != ISD::SUB ? ARM_AM::add:ARM_AM::sub; 855 ARM_AM::ShiftOpc ShOpcVal = 856 ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode()); 857 unsigned ShAmt = 0; 858 859 Base = N.getOperand(0); 860 Offset = N.getOperand(1); 861 862 if (ShOpcVal != ARM_AM::no_shift) { 863 // Check to see if the RHS of the shift is a constant, if not, we can't fold 864 // it. 865 if (ConstantSDNode *Sh = 866 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) { 867 ShAmt = Sh->getZExtValue(); 868 if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt)) 869 Offset = N.getOperand(1).getOperand(0); 870 else { 871 ShAmt = 0; 872 ShOpcVal = ARM_AM::no_shift; 873 } 874 } else { 875 ShOpcVal = ARM_AM::no_shift; 876 } 877 } 878 879 // Try matching (R shl C) + (R). 880 if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift && 881 !(Subtarget->isLikeA9() || Subtarget->isSwift() || 882 N.getOperand(0).hasOneUse())) { 883 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode()); 884 if (ShOpcVal != ARM_AM::no_shift) { 885 // Check to see if the RHS of the shift is a constant, if not, we can't 886 // fold it. 887 if (ConstantSDNode *Sh = 888 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) { 889 ShAmt = Sh->getZExtValue(); 890 if (isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt)) { 891 Offset = N.getOperand(0).getOperand(0); 892 Base = N.getOperand(1); 893 } else { 894 ShAmt = 0; 895 ShOpcVal = ARM_AM::no_shift; 896 } 897 } else { 898 ShOpcVal = ARM_AM::no_shift; 899 } 900 } 901 } 902 903 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 904 SDLoc(N), MVT::i32); 905 return AM2_SHOP; 906 } 907 908 bool ARMDAGToDAGISel::SelectAddrMode2OffsetReg(SDNode *Op, SDValue N, 909 SDValue &Offset, SDValue &Opc) { 910 unsigned Opcode = Op->getOpcode(); 911 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 912 ? cast<LoadSDNode>(Op)->getAddressingMode() 913 : cast<StoreSDNode>(Op)->getAddressingMode(); 914 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 915 ? ARM_AM::add : ARM_AM::sub; 916 int Val; 917 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) 918 return false; 919 920 Offset = N; 921 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); 922 unsigned ShAmt = 0; 923 if (ShOpcVal != ARM_AM::no_shift) { 924 // Check to see if the RHS of the shift is a constant, if not, we can't fold 925 // it. 926 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 927 ShAmt = Sh->getZExtValue(); 928 if (isShifterOpProfitable(N, ShOpcVal, ShAmt)) 929 Offset = N.getOperand(0); 930 else { 931 ShAmt = 0; 932 ShOpcVal = ARM_AM::no_shift; 933 } 934 } else { 935 ShOpcVal = ARM_AM::no_shift; 936 } 937 } 938 939 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 940 SDLoc(N), MVT::i32); 941 return true; 942 } 943 944 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N, 945 SDValue &Offset, SDValue &Opc) { 946 unsigned Opcode = Op->getOpcode(); 947 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 948 ? cast<LoadSDNode>(Op)->getAddressingMode() 949 : cast<StoreSDNode>(Op)->getAddressingMode(); 950 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 951 ? ARM_AM::add : ARM_AM::sub; 952 int Val; 953 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits. 954 if (AddSub == ARM_AM::sub) Val *= -1; 955 Offset = CurDAG->getRegister(0, MVT::i32); 956 Opc = CurDAG->getTargetConstant(Val, SDLoc(Op), MVT::i32); 957 return true; 958 } 959 960 return false; 961 } 962 963 964 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImm(SDNode *Op, SDValue N, 965 SDValue &Offset, SDValue &Opc) { 966 unsigned Opcode = Op->getOpcode(); 967 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 968 ? cast<LoadSDNode>(Op)->getAddressingMode() 969 : cast<StoreSDNode>(Op)->getAddressingMode(); 970 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 971 ? ARM_AM::add : ARM_AM::sub; 972 int Val; 973 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits. 974 Offset = CurDAG->getRegister(0, MVT::i32); 975 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, 976 ARM_AM::no_shift), 977 SDLoc(Op), MVT::i32); 978 return true; 979 } 980 981 return false; 982 } 983 984 bool ARMDAGToDAGISel::SelectAddrOffsetNone(SDValue N, SDValue &Base) { 985 Base = N; 986 return true; 987 } 988 989 bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N, 990 SDValue &Base, SDValue &Offset, 991 SDValue &Opc) { 992 if (N.getOpcode() == ISD::SUB) { 993 // X - C is canonicalize to X + -C, no need to handle it here. 994 Base = N.getOperand(0); 995 Offset = N.getOperand(1); 996 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0), SDLoc(N), 997 MVT::i32); 998 return true; 999 } 1000 1001 if (!CurDAG->isBaseWithConstantOffset(N)) { 1002 Base = N; 1003 if (N.getOpcode() == ISD::FrameIndex) { 1004 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1005 Base = CurDAG->getTargetFrameIndex( 1006 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1007 } 1008 Offset = CurDAG->getRegister(0, MVT::i32); 1009 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), SDLoc(N), 1010 MVT::i32); 1011 return true; 1012 } 1013 1014 // If the RHS is +/- imm8, fold into addr mode. 1015 int RHSC; 1016 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/1, 1017 -256 + 1, 256, RHSC)) { // 8 bits. 1018 Base = N.getOperand(0); 1019 if (Base.getOpcode() == ISD::FrameIndex) { 1020 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1021 Base = CurDAG->getTargetFrameIndex( 1022 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1023 } 1024 Offset = CurDAG->getRegister(0, MVT::i32); 1025 1026 ARM_AM::AddrOpc AddSub = ARM_AM::add; 1027 if (RHSC < 0) { 1028 AddSub = ARM_AM::sub; 1029 RHSC = -RHSC; 1030 } 1031 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC), SDLoc(N), 1032 MVT::i32); 1033 return true; 1034 } 1035 1036 Base = N.getOperand(0); 1037 Offset = N.getOperand(1); 1038 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), SDLoc(N), 1039 MVT::i32); 1040 return true; 1041 } 1042 1043 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N, 1044 SDValue &Offset, SDValue &Opc) { 1045 unsigned Opcode = Op->getOpcode(); 1046 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 1047 ? cast<LoadSDNode>(Op)->getAddressingMode() 1048 : cast<StoreSDNode>(Op)->getAddressingMode(); 1049 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 1050 ? ARM_AM::add : ARM_AM::sub; 1051 int Val; 1052 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 256, Val)) { // 12 bits. 1053 Offset = CurDAG->getRegister(0, MVT::i32); 1054 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), SDLoc(Op), 1055 MVT::i32); 1056 return true; 1057 } 1058 1059 Offset = N; 1060 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), SDLoc(Op), 1061 MVT::i32); 1062 return true; 1063 } 1064 1065 bool ARMDAGToDAGISel::SelectAddrMode5(SDValue N, 1066 SDValue &Base, SDValue &Offset) { 1067 if (!CurDAG->isBaseWithConstantOffset(N)) { 1068 Base = N; 1069 if (N.getOpcode() == ISD::FrameIndex) { 1070 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1071 Base = CurDAG->getTargetFrameIndex( 1072 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1073 } else if (N.getOpcode() == ARMISD::Wrapper && 1074 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress && 1075 N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol && 1076 N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) { 1077 Base = N.getOperand(0); 1078 } 1079 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 1080 SDLoc(N), MVT::i32); 1081 return true; 1082 } 1083 1084 // If the RHS is +/- imm8, fold into addr mode. 1085 int RHSC; 1086 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/4, 1087 -256 + 1, 256, RHSC)) { 1088 Base = N.getOperand(0); 1089 if (Base.getOpcode() == ISD::FrameIndex) { 1090 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1091 Base = CurDAG->getTargetFrameIndex( 1092 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1093 } 1094 1095 ARM_AM::AddrOpc AddSub = ARM_AM::add; 1096 if (RHSC < 0) { 1097 AddSub = ARM_AM::sub; 1098 RHSC = -RHSC; 1099 } 1100 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC), 1101 SDLoc(N), MVT::i32); 1102 return true; 1103 } 1104 1105 Base = N; 1106 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 1107 SDLoc(N), MVT::i32); 1108 return true; 1109 } 1110 1111 bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr, 1112 SDValue &Align) { 1113 Addr = N; 1114 1115 unsigned Alignment = 0; 1116 1117 MemSDNode *MemN = cast<MemSDNode>(Parent); 1118 1119 if (isa<LSBaseSDNode>(MemN) || 1120 ((MemN->getOpcode() == ARMISD::VST1_UPD || 1121 MemN->getOpcode() == ARMISD::VLD1_UPD) && 1122 MemN->getConstantOperandVal(MemN->getNumOperands() - 1) == 1)) { 1123 // This case occurs only for VLD1-lane/dup and VST1-lane instructions. 1124 // The maximum alignment is equal to the memory size being referenced. 1125 unsigned MMOAlign = MemN->getAlignment(); 1126 unsigned MemSize = MemN->getMemoryVT().getSizeInBits() / 8; 1127 if (MMOAlign >= MemSize && MemSize > 1) 1128 Alignment = MemSize; 1129 } else { 1130 // All other uses of addrmode6 are for intrinsics. For now just record 1131 // the raw alignment value; it will be refined later based on the legal 1132 // alignment operands for the intrinsic. 1133 Alignment = MemN->getAlignment(); 1134 } 1135 1136 Align = CurDAG->getTargetConstant(Alignment, SDLoc(N), MVT::i32); 1137 return true; 1138 } 1139 1140 bool ARMDAGToDAGISel::SelectAddrMode6Offset(SDNode *Op, SDValue N, 1141 SDValue &Offset) { 1142 LSBaseSDNode *LdSt = cast<LSBaseSDNode>(Op); 1143 ISD::MemIndexedMode AM = LdSt->getAddressingMode(); 1144 if (AM != ISD::POST_INC) 1145 return false; 1146 Offset = N; 1147 if (ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N)) { 1148 if (NC->getZExtValue() * 8 == LdSt->getMemoryVT().getSizeInBits()) 1149 Offset = CurDAG->getRegister(0, MVT::i32); 1150 } 1151 return true; 1152 } 1153 1154 bool ARMDAGToDAGISel::SelectAddrModePC(SDValue N, 1155 SDValue &Offset, SDValue &Label) { 1156 if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { 1157 Offset = N.getOperand(0); 1158 SDValue N1 = N.getOperand(1); 1159 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(), 1160 SDLoc(N), MVT::i32); 1161 return true; 1162 } 1163 1164 return false; 1165 } 1166 1167 1168 //===----------------------------------------------------------------------===// 1169 // Thumb Addressing Modes 1170 //===----------------------------------------------------------------------===// 1171 1172 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N, 1173 SDValue &Base, SDValue &Offset){ 1174 if (N.getOpcode() != ISD::ADD && !CurDAG->isBaseWithConstantOffset(N)) { 1175 ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N); 1176 if (!NC || !NC->isNullValue()) 1177 return false; 1178 1179 Base = Offset = N; 1180 return true; 1181 } 1182 1183 Base = N.getOperand(0); 1184 Offset = N.getOperand(1); 1185 return true; 1186 } 1187 1188 bool 1189 ARMDAGToDAGISel::SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, 1190 SDValue &Base, SDValue &OffImm) { 1191 if (!CurDAG->isBaseWithConstantOffset(N)) { 1192 if (N.getOpcode() == ISD::ADD) { 1193 return false; // We want to select register offset instead 1194 } else if (N.getOpcode() == ARMISD::Wrapper && 1195 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress && 1196 N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol && 1197 N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) { 1198 Base = N.getOperand(0); 1199 } else { 1200 Base = N; 1201 } 1202 1203 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1204 return true; 1205 } 1206 1207 // If the RHS is + imm5 * scale, fold into addr mode. 1208 int RHSC; 1209 if (isScaledConstantInRange(N.getOperand(1), Scale, 0, 32, RHSC)) { 1210 Base = N.getOperand(0); 1211 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 1212 return true; 1213 } 1214 1215 // Offset is too large, so use register offset instead. 1216 return false; 1217 } 1218 1219 bool 1220 ARMDAGToDAGISel::SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base, 1221 SDValue &OffImm) { 1222 return SelectThumbAddrModeImm5S(N, 4, Base, OffImm); 1223 } 1224 1225 bool 1226 ARMDAGToDAGISel::SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base, 1227 SDValue &OffImm) { 1228 return SelectThumbAddrModeImm5S(N, 2, Base, OffImm); 1229 } 1230 1231 bool 1232 ARMDAGToDAGISel::SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base, 1233 SDValue &OffImm) { 1234 return SelectThumbAddrModeImm5S(N, 1, Base, OffImm); 1235 } 1236 1237 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue N, 1238 SDValue &Base, SDValue &OffImm) { 1239 if (N.getOpcode() == ISD::FrameIndex) { 1240 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1241 // Only multiples of 4 are allowed for the offset, so the frame object 1242 // alignment must be at least 4. 1243 MachineFrameInfo *MFI = MF->getFrameInfo(); 1244 if (MFI->getObjectAlignment(FI) < 4) 1245 MFI->setObjectAlignment(FI, 4); 1246 Base = CurDAG->getTargetFrameIndex( 1247 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1248 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1249 return true; 1250 } 1251 1252 if (!CurDAG->isBaseWithConstantOffset(N)) 1253 return false; 1254 1255 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 1256 if (N.getOperand(0).getOpcode() == ISD::FrameIndex || 1257 (LHSR && LHSR->getReg() == ARM::SP)) { 1258 // If the RHS is + imm8 * scale, fold into addr mode. 1259 int RHSC; 1260 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/4, 0, 256, RHSC)) { 1261 Base = N.getOperand(0); 1262 if (Base.getOpcode() == ISD::FrameIndex) { 1263 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1264 // For LHS+RHS to result in an offset that's a multiple of 4 the object 1265 // indexed by the LHS must be 4-byte aligned. 1266 MachineFrameInfo *MFI = MF->getFrameInfo(); 1267 if (MFI->getObjectAlignment(FI) < 4) 1268 MFI->setObjectAlignment(FI, 4); 1269 Base = CurDAG->getTargetFrameIndex( 1270 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1271 } 1272 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 1273 return true; 1274 } 1275 } 1276 1277 return false; 1278 } 1279 1280 1281 //===----------------------------------------------------------------------===// 1282 // Thumb 2 Addressing Modes 1283 //===----------------------------------------------------------------------===// 1284 1285 1286 bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue N, 1287 SDValue &Base, SDValue &OffImm) { 1288 // Match simple R + imm12 operands. 1289 1290 // Base only. 1291 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && 1292 !CurDAG->isBaseWithConstantOffset(N)) { 1293 if (N.getOpcode() == ISD::FrameIndex) { 1294 // Match frame index. 1295 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1296 Base = CurDAG->getTargetFrameIndex( 1297 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1298 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1299 return true; 1300 } 1301 1302 if (N.getOpcode() == ARMISD::Wrapper && 1303 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress && 1304 N.getOperand(0).getOpcode() != ISD::TargetExternalSymbol && 1305 N.getOperand(0).getOpcode() != ISD::TargetGlobalTLSAddress) { 1306 Base = N.getOperand(0); 1307 if (Base.getOpcode() == ISD::TargetConstantPool) 1308 return false; // We want to select t2LDRpci instead. 1309 } else 1310 Base = N; 1311 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1312 return true; 1313 } 1314 1315 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 1316 if (SelectT2AddrModeImm8(N, Base, OffImm)) 1317 // Let t2LDRi8 handle (R - imm8). 1318 return false; 1319 1320 int RHSC = (int)RHS->getZExtValue(); 1321 if (N.getOpcode() == ISD::SUB) 1322 RHSC = -RHSC; 1323 1324 if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits (unsigned) 1325 Base = N.getOperand(0); 1326 if (Base.getOpcode() == ISD::FrameIndex) { 1327 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1328 Base = CurDAG->getTargetFrameIndex( 1329 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1330 } 1331 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 1332 return true; 1333 } 1334 } 1335 1336 // Base only. 1337 Base = N; 1338 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1339 return true; 1340 } 1341 1342 bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue N, 1343 SDValue &Base, SDValue &OffImm) { 1344 // Match simple R - imm8 operands. 1345 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && 1346 !CurDAG->isBaseWithConstantOffset(N)) 1347 return false; 1348 1349 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 1350 int RHSC = (int)RHS->getSExtValue(); 1351 if (N.getOpcode() == ISD::SUB) 1352 RHSC = -RHSC; 1353 1354 if ((RHSC >= -255) && (RHSC < 0)) { // 8 bits (always negative) 1355 Base = N.getOperand(0); 1356 if (Base.getOpcode() == ISD::FrameIndex) { 1357 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1358 Base = CurDAG->getTargetFrameIndex( 1359 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1360 } 1361 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32); 1362 return true; 1363 } 1364 } 1365 1366 return false; 1367 } 1368 1369 bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 1370 SDValue &OffImm){ 1371 unsigned Opcode = Op->getOpcode(); 1372 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 1373 ? cast<LoadSDNode>(Op)->getAddressingMode() 1374 : cast<StoreSDNode>(Op)->getAddressingMode(); 1375 int RHSC; 1376 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x100, RHSC)) { // 8 bits. 1377 OffImm = ((AM == ISD::PRE_INC) || (AM == ISD::POST_INC)) 1378 ? CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32) 1379 : CurDAG->getTargetConstant(-RHSC, SDLoc(N), MVT::i32); 1380 return true; 1381 } 1382 1383 return false; 1384 } 1385 1386 bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue N, 1387 SDValue &Base, 1388 SDValue &OffReg, SDValue &ShImm) { 1389 // (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12. 1390 if (N.getOpcode() != ISD::ADD && !CurDAG->isBaseWithConstantOffset(N)) 1391 return false; 1392 1393 // Leave (R + imm12) for t2LDRi12, (R - imm8) for t2LDRi8. 1394 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 1395 int RHSC = (int)RHS->getZExtValue(); 1396 if (RHSC >= 0 && RHSC < 0x1000) // 12 bits (unsigned) 1397 return false; 1398 else if (RHSC < 0 && RHSC >= -255) // 8 bits 1399 return false; 1400 } 1401 1402 // Look for (R + R) or (R + (R << [1,2,3])). 1403 unsigned ShAmt = 0; 1404 Base = N.getOperand(0); 1405 OffReg = N.getOperand(1); 1406 1407 // Swap if it is ((R << c) + R). 1408 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg.getOpcode()); 1409 if (ShOpcVal != ARM_AM::lsl) { 1410 ShOpcVal = ARM_AM::getShiftOpcForNode(Base.getOpcode()); 1411 if (ShOpcVal == ARM_AM::lsl) 1412 std::swap(Base, OffReg); 1413 } 1414 1415 if (ShOpcVal == ARM_AM::lsl) { 1416 // Check to see if the RHS of the shift is a constant, if not, we can't fold 1417 // it. 1418 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(OffReg.getOperand(1))) { 1419 ShAmt = Sh->getZExtValue(); 1420 if (ShAmt < 4 && isShifterOpProfitable(OffReg, ShOpcVal, ShAmt)) 1421 OffReg = OffReg.getOperand(0); 1422 else { 1423 ShAmt = 0; 1424 } 1425 } 1426 } 1427 1428 // If OffReg is a multiply-by-constant and it's profitable to extract a shift 1429 // and use it in a shifted operand do so. 1430 if (OffReg.getOpcode() == ISD::MUL && N.hasOneUse()) { 1431 unsigned PowerOfTwo = 0; 1432 SDValue NewMulConst; 1433 if (canExtractShiftFromMul(OffReg, 3, PowerOfTwo, NewMulConst)) { 1434 replaceDAGValue(OffReg.getOperand(1), NewMulConst); 1435 ShAmt = PowerOfTwo; 1436 } 1437 } 1438 1439 ShImm = CurDAG->getTargetConstant(ShAmt, SDLoc(N), MVT::i32); 1440 1441 return true; 1442 } 1443 1444 bool ARMDAGToDAGISel::SelectT2AddrModeExclusive(SDValue N, SDValue &Base, 1445 SDValue &OffImm) { 1446 // This *must* succeed since it's used for the irreplaceable ldrex and strex 1447 // instructions. 1448 Base = N; 1449 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32); 1450 1451 if (N.getOpcode() != ISD::ADD || !CurDAG->isBaseWithConstantOffset(N)) 1452 return true; 1453 1454 ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1)); 1455 if (!RHS) 1456 return true; 1457 1458 uint32_t RHSC = (int)RHS->getZExtValue(); 1459 if (RHSC > 1020 || RHSC % 4 != 0) 1460 return true; 1461 1462 Base = N.getOperand(0); 1463 if (Base.getOpcode() == ISD::FrameIndex) { 1464 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1465 Base = CurDAG->getTargetFrameIndex( 1466 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1467 } 1468 1469 OffImm = CurDAG->getTargetConstant(RHSC/4, SDLoc(N), MVT::i32); 1470 return true; 1471 } 1472 1473 //===--------------------------------------------------------------------===// 1474 1475 /// getAL - Returns a ARMCC::AL immediate node. 1476 static inline SDValue getAL(SelectionDAG *CurDAG, SDLoc dl) { 1477 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, dl, MVT::i32); 1478 } 1479 1480 SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDNode *N) { 1481 LoadSDNode *LD = cast<LoadSDNode>(N); 1482 ISD::MemIndexedMode AM = LD->getAddressingMode(); 1483 if (AM == ISD::UNINDEXED) 1484 return nullptr; 1485 1486 EVT LoadedVT = LD->getMemoryVT(); 1487 SDValue Offset, AMOpc; 1488 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 1489 unsigned Opcode = 0; 1490 bool Match = false; 1491 if (LoadedVT == MVT::i32 && isPre && 1492 SelectAddrMode2OffsetImmPre(N, LD->getOffset(), Offset, AMOpc)) { 1493 Opcode = ARM::LDR_PRE_IMM; 1494 Match = true; 1495 } else if (LoadedVT == MVT::i32 && !isPre && 1496 SelectAddrMode2OffsetImm(N, LD->getOffset(), Offset, AMOpc)) { 1497 Opcode = ARM::LDR_POST_IMM; 1498 Match = true; 1499 } else if (LoadedVT == MVT::i32 && 1500 SelectAddrMode2OffsetReg(N, LD->getOffset(), Offset, AMOpc)) { 1501 Opcode = isPre ? ARM::LDR_PRE_REG : ARM::LDR_POST_REG; 1502 Match = true; 1503 1504 } else if (LoadedVT == MVT::i16 && 1505 SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 1506 Match = true; 1507 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) 1508 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) 1509 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); 1510 } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) { 1511 if (LD->getExtensionType() == ISD::SEXTLOAD) { 1512 if (SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 1513 Match = true; 1514 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; 1515 } 1516 } else { 1517 if (isPre && 1518 SelectAddrMode2OffsetImmPre(N, LD->getOffset(), Offset, AMOpc)) { 1519 Match = true; 1520 Opcode = ARM::LDRB_PRE_IMM; 1521 } else if (!isPre && 1522 SelectAddrMode2OffsetImm(N, LD->getOffset(), Offset, AMOpc)) { 1523 Match = true; 1524 Opcode = ARM::LDRB_POST_IMM; 1525 } else if (SelectAddrMode2OffsetReg(N, LD->getOffset(), Offset, AMOpc)) { 1526 Match = true; 1527 Opcode = isPre ? ARM::LDRB_PRE_REG : ARM::LDRB_POST_REG; 1528 } 1529 } 1530 } 1531 1532 if (Match) { 1533 if (Opcode == ARM::LDR_PRE_IMM || Opcode == ARM::LDRB_PRE_IMM) { 1534 SDValue Chain = LD->getChain(); 1535 SDValue Base = LD->getBasePtr(); 1536 SDValue Ops[]= { Base, AMOpc, getAL(CurDAG, SDLoc(N)), 1537 CurDAG->getRegister(0, MVT::i32), Chain }; 1538 return CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i32, 1539 MVT::i32, MVT::Other, Ops); 1540 } else { 1541 SDValue Chain = LD->getChain(); 1542 SDValue Base = LD->getBasePtr(); 1543 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG, SDLoc(N)), 1544 CurDAG->getRegister(0, MVT::i32), Chain }; 1545 return CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i32, 1546 MVT::i32, MVT::Other, Ops); 1547 } 1548 } 1549 1550 return nullptr; 1551 } 1552 1553 SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) { 1554 LoadSDNode *LD = cast<LoadSDNode>(N); 1555 ISD::MemIndexedMode AM = LD->getAddressingMode(); 1556 if (AM == ISD::UNINDEXED) 1557 return nullptr; 1558 1559 EVT LoadedVT = LD->getMemoryVT(); 1560 bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD; 1561 SDValue Offset; 1562 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 1563 unsigned Opcode = 0; 1564 bool Match = false; 1565 if (SelectT2AddrModeImm8Offset(N, LD->getOffset(), Offset)) { 1566 switch (LoadedVT.getSimpleVT().SimpleTy) { 1567 case MVT::i32: 1568 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST; 1569 break; 1570 case MVT::i16: 1571 if (isSExtLd) 1572 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST; 1573 else 1574 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST; 1575 break; 1576 case MVT::i8: 1577 case MVT::i1: 1578 if (isSExtLd) 1579 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST; 1580 else 1581 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST; 1582 break; 1583 default: 1584 return nullptr; 1585 } 1586 Match = true; 1587 } 1588 1589 if (Match) { 1590 SDValue Chain = LD->getChain(); 1591 SDValue Base = LD->getBasePtr(); 1592 SDValue Ops[]= { Base, Offset, getAL(CurDAG, SDLoc(N)), 1593 CurDAG->getRegister(0, MVT::i32), Chain }; 1594 return CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i32, MVT::i32, 1595 MVT::Other, Ops); 1596 } 1597 1598 return nullptr; 1599 } 1600 1601 /// \brief Form a GPRPair pseudo register from a pair of GPR regs. 1602 SDNode *ARMDAGToDAGISel::createGPRPairNode(EVT VT, SDValue V0, SDValue V1) { 1603 SDLoc dl(V0.getNode()); 1604 SDValue RegClass = 1605 CurDAG->getTargetConstant(ARM::GPRPairRegClassID, dl, MVT::i32); 1606 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::gsub_0, dl, MVT::i32); 1607 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::gsub_1, dl, MVT::i32); 1608 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 }; 1609 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1610 } 1611 1612 /// \brief Form a D register from a pair of S registers. 1613 SDNode *ARMDAGToDAGISel::createSRegPairNode(EVT VT, SDValue V0, SDValue V1) { 1614 SDLoc dl(V0.getNode()); 1615 SDValue RegClass = 1616 CurDAG->getTargetConstant(ARM::DPR_VFP2RegClassID, dl, MVT::i32); 1617 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, dl, MVT::i32); 1618 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, dl, MVT::i32); 1619 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 }; 1620 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1621 } 1622 1623 /// \brief Form a quad register from a pair of D registers. 1624 SDNode *ARMDAGToDAGISel::createDRegPairNode(EVT VT, SDValue V0, SDValue V1) { 1625 SDLoc dl(V0.getNode()); 1626 SDValue RegClass = CurDAG->getTargetConstant(ARM::QPRRegClassID, dl, 1627 MVT::i32); 1628 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, dl, MVT::i32); 1629 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, dl, MVT::i32); 1630 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 }; 1631 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1632 } 1633 1634 /// \brief Form 4 consecutive D registers from a pair of Q registers. 1635 SDNode *ARMDAGToDAGISel::createQRegPairNode(EVT VT, SDValue V0, SDValue V1) { 1636 SDLoc dl(V0.getNode()); 1637 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, dl, 1638 MVT::i32); 1639 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, dl, MVT::i32); 1640 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, dl, MVT::i32); 1641 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 }; 1642 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1643 } 1644 1645 /// \brief Form 4 consecutive S registers. 1646 SDNode *ARMDAGToDAGISel::createQuadSRegsNode(EVT VT, SDValue V0, SDValue V1, 1647 SDValue V2, SDValue V3) { 1648 SDLoc dl(V0.getNode()); 1649 SDValue RegClass = 1650 CurDAG->getTargetConstant(ARM::QPR_VFP2RegClassID, dl, MVT::i32); 1651 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, dl, MVT::i32); 1652 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, dl, MVT::i32); 1653 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, dl, MVT::i32); 1654 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, dl, MVT::i32); 1655 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1, 1656 V2, SubReg2, V3, SubReg3 }; 1657 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1658 } 1659 1660 /// \brief Form 4 consecutive D registers. 1661 SDNode *ARMDAGToDAGISel::createQuadDRegsNode(EVT VT, SDValue V0, SDValue V1, 1662 SDValue V2, SDValue V3) { 1663 SDLoc dl(V0.getNode()); 1664 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, dl, 1665 MVT::i32); 1666 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, dl, MVT::i32); 1667 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, dl, MVT::i32); 1668 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, dl, MVT::i32); 1669 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, dl, MVT::i32); 1670 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1, 1671 V2, SubReg2, V3, SubReg3 }; 1672 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1673 } 1674 1675 /// \brief Form 4 consecutive Q registers. 1676 SDNode *ARMDAGToDAGISel::createQuadQRegsNode(EVT VT, SDValue V0, SDValue V1, 1677 SDValue V2, SDValue V3) { 1678 SDLoc dl(V0.getNode()); 1679 SDValue RegClass = CurDAG->getTargetConstant(ARM::QQQQPRRegClassID, dl, 1680 MVT::i32); 1681 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, dl, MVT::i32); 1682 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, dl, MVT::i32); 1683 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, dl, MVT::i32); 1684 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, dl, MVT::i32); 1685 const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1, 1686 V2, SubReg2, V3, SubReg3 }; 1687 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops); 1688 } 1689 1690 /// GetVLDSTAlign - Get the alignment (in bytes) for the alignment operand 1691 /// of a NEON VLD or VST instruction. The supported values depend on the 1692 /// number of registers being loaded. 1693 SDValue ARMDAGToDAGISel::GetVLDSTAlign(SDValue Align, SDLoc dl, 1694 unsigned NumVecs, bool is64BitVector) { 1695 unsigned NumRegs = NumVecs; 1696 if (!is64BitVector && NumVecs < 3) 1697 NumRegs *= 2; 1698 1699 unsigned Alignment = cast<ConstantSDNode>(Align)->getZExtValue(); 1700 if (Alignment >= 32 && NumRegs == 4) 1701 Alignment = 32; 1702 else if (Alignment >= 16 && (NumRegs == 2 || NumRegs == 4)) 1703 Alignment = 16; 1704 else if (Alignment >= 8) 1705 Alignment = 8; 1706 else 1707 Alignment = 0; 1708 1709 return CurDAG->getTargetConstant(Alignment, dl, MVT::i32); 1710 } 1711 1712 static bool isVLDfixed(unsigned Opc) 1713 { 1714 switch (Opc) { 1715 default: return false; 1716 case ARM::VLD1d8wb_fixed : return true; 1717 case ARM::VLD1d16wb_fixed : return true; 1718 case ARM::VLD1d64Qwb_fixed : return true; 1719 case ARM::VLD1d32wb_fixed : return true; 1720 case ARM::VLD1d64wb_fixed : return true; 1721 case ARM::VLD1d64TPseudoWB_fixed : return true; 1722 case ARM::VLD1d64QPseudoWB_fixed : return true; 1723 case ARM::VLD1q8wb_fixed : return true; 1724 case ARM::VLD1q16wb_fixed : return true; 1725 case ARM::VLD1q32wb_fixed : return true; 1726 case ARM::VLD1q64wb_fixed : return true; 1727 case ARM::VLD2d8wb_fixed : return true; 1728 case ARM::VLD2d16wb_fixed : return true; 1729 case ARM::VLD2d32wb_fixed : return true; 1730 case ARM::VLD2q8PseudoWB_fixed : return true; 1731 case ARM::VLD2q16PseudoWB_fixed : return true; 1732 case ARM::VLD2q32PseudoWB_fixed : return true; 1733 case ARM::VLD2DUPd8wb_fixed : return true; 1734 case ARM::VLD2DUPd16wb_fixed : return true; 1735 case ARM::VLD2DUPd32wb_fixed : return true; 1736 } 1737 } 1738 1739 static bool isVSTfixed(unsigned Opc) 1740 { 1741 switch (Opc) { 1742 default: return false; 1743 case ARM::VST1d8wb_fixed : return true; 1744 case ARM::VST1d16wb_fixed : return true; 1745 case ARM::VST1d32wb_fixed : return true; 1746 case ARM::VST1d64wb_fixed : return true; 1747 case ARM::VST1q8wb_fixed : return true; 1748 case ARM::VST1q16wb_fixed : return true; 1749 case ARM::VST1q32wb_fixed : return true; 1750 case ARM::VST1q64wb_fixed : return true; 1751 case ARM::VST1d64TPseudoWB_fixed : return true; 1752 case ARM::VST1d64QPseudoWB_fixed : return true; 1753 case ARM::VST2d8wb_fixed : return true; 1754 case ARM::VST2d16wb_fixed : return true; 1755 case ARM::VST2d32wb_fixed : return true; 1756 case ARM::VST2q8PseudoWB_fixed : return true; 1757 case ARM::VST2q16PseudoWB_fixed : return true; 1758 case ARM::VST2q32PseudoWB_fixed : return true; 1759 } 1760 } 1761 1762 // Get the register stride update opcode of a VLD/VST instruction that 1763 // is otherwise equivalent to the given fixed stride updating instruction. 1764 static unsigned getVLDSTRegisterUpdateOpcode(unsigned Opc) { 1765 assert((isVLDfixed(Opc) || isVSTfixed(Opc)) 1766 && "Incorrect fixed stride updating instruction."); 1767 switch (Opc) { 1768 default: break; 1769 case ARM::VLD1d8wb_fixed: return ARM::VLD1d8wb_register; 1770 case ARM::VLD1d16wb_fixed: return ARM::VLD1d16wb_register; 1771 case ARM::VLD1d32wb_fixed: return ARM::VLD1d32wb_register; 1772 case ARM::VLD1d64wb_fixed: return ARM::VLD1d64wb_register; 1773 case ARM::VLD1q8wb_fixed: return ARM::VLD1q8wb_register; 1774 case ARM::VLD1q16wb_fixed: return ARM::VLD1q16wb_register; 1775 case ARM::VLD1q32wb_fixed: return ARM::VLD1q32wb_register; 1776 case ARM::VLD1q64wb_fixed: return ARM::VLD1q64wb_register; 1777 case ARM::VLD1d64Twb_fixed: return ARM::VLD1d64Twb_register; 1778 case ARM::VLD1d64Qwb_fixed: return ARM::VLD1d64Qwb_register; 1779 case ARM::VLD1d64TPseudoWB_fixed: return ARM::VLD1d64TPseudoWB_register; 1780 case ARM::VLD1d64QPseudoWB_fixed: return ARM::VLD1d64QPseudoWB_register; 1781 1782 case ARM::VST1d8wb_fixed: return ARM::VST1d8wb_register; 1783 case ARM::VST1d16wb_fixed: return ARM::VST1d16wb_register; 1784 case ARM::VST1d32wb_fixed: return ARM::VST1d32wb_register; 1785 case ARM::VST1d64wb_fixed: return ARM::VST1d64wb_register; 1786 case ARM::VST1q8wb_fixed: return ARM::VST1q8wb_register; 1787 case ARM::VST1q16wb_fixed: return ARM::VST1q16wb_register; 1788 case ARM::VST1q32wb_fixed: return ARM::VST1q32wb_register; 1789 case ARM::VST1q64wb_fixed: return ARM::VST1q64wb_register; 1790 case ARM::VST1d64TPseudoWB_fixed: return ARM::VST1d64TPseudoWB_register; 1791 case ARM::VST1d64QPseudoWB_fixed: return ARM::VST1d64QPseudoWB_register; 1792 1793 case ARM::VLD2d8wb_fixed: return ARM::VLD2d8wb_register; 1794 case ARM::VLD2d16wb_fixed: return ARM::VLD2d16wb_register; 1795 case ARM::VLD2d32wb_fixed: return ARM::VLD2d32wb_register; 1796 case ARM::VLD2q8PseudoWB_fixed: return ARM::VLD2q8PseudoWB_register; 1797 case ARM::VLD2q16PseudoWB_fixed: return ARM::VLD2q16PseudoWB_register; 1798 case ARM::VLD2q32PseudoWB_fixed: return ARM::VLD2q32PseudoWB_register; 1799 1800 case ARM::VST2d8wb_fixed: return ARM::VST2d8wb_register; 1801 case ARM::VST2d16wb_fixed: return ARM::VST2d16wb_register; 1802 case ARM::VST2d32wb_fixed: return ARM::VST2d32wb_register; 1803 case ARM::VST2q8PseudoWB_fixed: return ARM::VST2q8PseudoWB_register; 1804 case ARM::VST2q16PseudoWB_fixed: return ARM::VST2q16PseudoWB_register; 1805 case ARM::VST2q32PseudoWB_fixed: return ARM::VST2q32PseudoWB_register; 1806 1807 case ARM::VLD2DUPd8wb_fixed: return ARM::VLD2DUPd8wb_register; 1808 case ARM::VLD2DUPd16wb_fixed: return ARM::VLD2DUPd16wb_register; 1809 case ARM::VLD2DUPd32wb_fixed: return ARM::VLD2DUPd32wb_register; 1810 } 1811 return Opc; // If not one we handle, return it unchanged. 1812 } 1813 1814 SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs, 1815 const uint16_t *DOpcodes, 1816 const uint16_t *QOpcodes0, 1817 const uint16_t *QOpcodes1) { 1818 assert(NumVecs >= 1 && NumVecs <= 4 && "VLD NumVecs out-of-range"); 1819 SDLoc dl(N); 1820 1821 SDValue MemAddr, Align; 1822 unsigned AddrOpIdx = isUpdating ? 1 : 2; 1823 if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align)) 1824 return nullptr; 1825 1826 SDValue Chain = N->getOperand(0); 1827 EVT VT = N->getValueType(0); 1828 bool is64BitVector = VT.is64BitVector(); 1829 Align = GetVLDSTAlign(Align, dl, NumVecs, is64BitVector); 1830 1831 unsigned OpcodeIndex; 1832 switch (VT.getSimpleVT().SimpleTy) { 1833 default: llvm_unreachable("unhandled vld type"); 1834 // Double-register operations: 1835 case MVT::v8i8: OpcodeIndex = 0; break; 1836 case MVT::v4i16: OpcodeIndex = 1; break; 1837 case MVT::v2f32: 1838 case MVT::v2i32: OpcodeIndex = 2; break; 1839 case MVT::v1i64: OpcodeIndex = 3; break; 1840 // Quad-register operations: 1841 case MVT::v16i8: OpcodeIndex = 0; break; 1842 case MVT::v8i16: OpcodeIndex = 1; break; 1843 case MVT::v4f32: 1844 case MVT::v4i32: OpcodeIndex = 2; break; 1845 case MVT::v2f64: 1846 case MVT::v2i64: OpcodeIndex = 3; 1847 assert(NumVecs == 1 && "v2i64 type only supported for VLD1"); 1848 break; 1849 } 1850 1851 EVT ResTy; 1852 if (NumVecs == 1) 1853 ResTy = VT; 1854 else { 1855 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs; 1856 if (!is64BitVector) 1857 ResTyElts *= 2; 1858 ResTy = EVT::getVectorVT(*CurDAG->getContext(), MVT::i64, ResTyElts); 1859 } 1860 std::vector<EVT> ResTys; 1861 ResTys.push_back(ResTy); 1862 if (isUpdating) 1863 ResTys.push_back(MVT::i32); 1864 ResTys.push_back(MVT::Other); 1865 1866 SDValue Pred = getAL(CurDAG, dl); 1867 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1868 SDNode *VLd; 1869 SmallVector<SDValue, 7> Ops; 1870 1871 // Double registers and VLD1/VLD2 quad registers are directly supported. 1872 if (is64BitVector || NumVecs <= 2) { 1873 unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] : 1874 QOpcodes0[OpcodeIndex]); 1875 Ops.push_back(MemAddr); 1876 Ops.push_back(Align); 1877 if (isUpdating) { 1878 SDValue Inc = N->getOperand(AddrOpIdx + 1); 1879 // FIXME: VLD1/VLD2 fixed increment doesn't need Reg0. Remove the reg0 1880 // case entirely when the rest are updated to that form, too. 1881 if ((NumVecs <= 2) && !isa<ConstantSDNode>(Inc.getNode())) 1882 Opc = getVLDSTRegisterUpdateOpcode(Opc); 1883 // FIXME: We use a VLD1 for v1i64 even if the pseudo says vld2/3/4, so 1884 // check for that explicitly too. Horribly hacky, but temporary. 1885 if ((NumVecs > 2 && !isVLDfixed(Opc)) || 1886 !isa<ConstantSDNode>(Inc.getNode())) 1887 Ops.push_back(isa<ConstantSDNode>(Inc.getNode()) ? Reg0 : Inc); 1888 } 1889 Ops.push_back(Pred); 1890 Ops.push_back(Reg0); 1891 Ops.push_back(Chain); 1892 VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 1893 1894 } else { 1895 // Otherwise, quad registers are loaded with two separate instructions, 1896 // where one loads the even registers and the other loads the odd registers. 1897 EVT AddrTy = MemAddr.getValueType(); 1898 1899 // Load the even subregs. This is always an updating load, so that it 1900 // provides the address to the second load for the odd subregs. 1901 SDValue ImplDef = 1902 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy), 0); 1903 const SDValue OpsA[] = { MemAddr, Align, Reg0, ImplDef, Pred, Reg0, Chain }; 1904 SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl, 1905 ResTy, AddrTy, MVT::Other, OpsA); 1906 Chain = SDValue(VLdA, 2); 1907 1908 // Load the odd subregs. 1909 Ops.push_back(SDValue(VLdA, 1)); 1910 Ops.push_back(Align); 1911 if (isUpdating) { 1912 SDValue Inc = N->getOperand(AddrOpIdx + 1); 1913 assert(isa<ConstantSDNode>(Inc.getNode()) && 1914 "only constant post-increment update allowed for VLD3/4"); 1915 (void)Inc; 1916 Ops.push_back(Reg0); 1917 } 1918 Ops.push_back(SDValue(VLdA, 0)); 1919 Ops.push_back(Pred); 1920 Ops.push_back(Reg0); 1921 Ops.push_back(Chain); 1922 VLd = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, Ops); 1923 } 1924 1925 // Transfer memoperands. 1926 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 1927 MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 1928 cast<MachineSDNode>(VLd)->setMemRefs(MemOp, MemOp + 1); 1929 1930 if (NumVecs == 1) 1931 return VLd; 1932 1933 // Extract out the subregisters. 1934 SDValue SuperReg = SDValue(VLd, 0); 1935 assert(ARM::dsub_7 == ARM::dsub_0+7 && 1936 ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering"); 1937 unsigned Sub0 = (is64BitVector ? ARM::dsub_0 : ARM::qsub_0); 1938 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1939 ReplaceUses(SDValue(N, Vec), 1940 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg)); 1941 ReplaceUses(SDValue(N, NumVecs), SDValue(VLd, 1)); 1942 if (isUpdating) 1943 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(VLd, 2)); 1944 return nullptr; 1945 } 1946 1947 SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, bool isUpdating, unsigned NumVecs, 1948 const uint16_t *DOpcodes, 1949 const uint16_t *QOpcodes0, 1950 const uint16_t *QOpcodes1) { 1951 assert(NumVecs >= 1 && NumVecs <= 4 && "VST NumVecs out-of-range"); 1952 SDLoc dl(N); 1953 1954 SDValue MemAddr, Align; 1955 unsigned AddrOpIdx = isUpdating ? 1 : 2; 1956 unsigned Vec0Idx = 3; // AddrOpIdx + (isUpdating ? 2 : 1) 1957 if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align)) 1958 return nullptr; 1959 1960 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 1961 MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 1962 1963 SDValue Chain = N->getOperand(0); 1964 EVT VT = N->getOperand(Vec0Idx).getValueType(); 1965 bool is64BitVector = VT.is64BitVector(); 1966 Align = GetVLDSTAlign(Align, dl, NumVecs, is64BitVector); 1967 1968 unsigned OpcodeIndex; 1969 switch (VT.getSimpleVT().SimpleTy) { 1970 default: llvm_unreachable("unhandled vst type"); 1971 // Double-register operations: 1972 case MVT::v8i8: OpcodeIndex = 0; break; 1973 case MVT::v4i16: OpcodeIndex = 1; break; 1974 case MVT::v2f32: 1975 case MVT::v2i32: OpcodeIndex = 2; break; 1976 case MVT::v1i64: OpcodeIndex = 3; break; 1977 // Quad-register operations: 1978 case MVT::v16i8: OpcodeIndex = 0; break; 1979 case MVT::v8i16: OpcodeIndex = 1; break; 1980 case MVT::v4f32: 1981 case MVT::v4i32: OpcodeIndex = 2; break; 1982 case MVT::v2f64: 1983 case MVT::v2i64: OpcodeIndex = 3; 1984 assert(NumVecs == 1 && "v2i64 type only supported for VST1"); 1985 break; 1986 } 1987 1988 std::vector<EVT> ResTys; 1989 if (isUpdating) 1990 ResTys.push_back(MVT::i32); 1991 ResTys.push_back(MVT::Other); 1992 1993 SDValue Pred = getAL(CurDAG, dl); 1994 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1995 SmallVector<SDValue, 7> Ops; 1996 1997 // Double registers and VST1/VST2 quad registers are directly supported. 1998 if (is64BitVector || NumVecs <= 2) { 1999 SDValue SrcReg; 2000 if (NumVecs == 1) { 2001 SrcReg = N->getOperand(Vec0Idx); 2002 } else if (is64BitVector) { 2003 // Form a REG_SEQUENCE to force register allocation. 2004 SDValue V0 = N->getOperand(Vec0Idx + 0); 2005 SDValue V1 = N->getOperand(Vec0Idx + 1); 2006 if (NumVecs == 2) 2007 SrcReg = SDValue(createDRegPairNode(MVT::v2i64, V0, V1), 0); 2008 else { 2009 SDValue V2 = N->getOperand(Vec0Idx + 2); 2010 // If it's a vst3, form a quad D-register and leave the last part as 2011 // an undef. 2012 SDValue V3 = (NumVecs == 3) 2013 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0) 2014 : N->getOperand(Vec0Idx + 3); 2015 SrcReg = SDValue(createQuadDRegsNode(MVT::v4i64, V0, V1, V2, V3), 0); 2016 } 2017 } else { 2018 // Form a QQ register. 2019 SDValue Q0 = N->getOperand(Vec0Idx); 2020 SDValue Q1 = N->getOperand(Vec0Idx + 1); 2021 SrcReg = SDValue(createQRegPairNode(MVT::v4i64, Q0, Q1), 0); 2022 } 2023 2024 unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] : 2025 QOpcodes0[OpcodeIndex]); 2026 Ops.push_back(MemAddr); 2027 Ops.push_back(Align); 2028 if (isUpdating) { 2029 SDValue Inc = N->getOperand(AddrOpIdx + 1); 2030 // FIXME: VST1/VST2 fixed increment doesn't need Reg0. Remove the reg0 2031 // case entirely when the rest are updated to that form, too. 2032 if (NumVecs <= 2 && !isa<ConstantSDNode>(Inc.getNode())) 2033 Opc = getVLDSTRegisterUpdateOpcode(Opc); 2034 // FIXME: We use a VST1 for v1i64 even if the pseudo says vld2/3/4, so 2035 // check for that explicitly too. Horribly hacky, but temporary. 2036 if (!isa<ConstantSDNode>(Inc.getNode())) 2037 Ops.push_back(Inc); 2038 else if (NumVecs > 2 && !isVSTfixed(Opc)) 2039 Ops.push_back(Reg0); 2040 } 2041 Ops.push_back(SrcReg); 2042 Ops.push_back(Pred); 2043 Ops.push_back(Reg0); 2044 Ops.push_back(Chain); 2045 SDNode *VSt = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 2046 2047 // Transfer memoperands. 2048 cast<MachineSDNode>(VSt)->setMemRefs(MemOp, MemOp + 1); 2049 2050 return VSt; 2051 } 2052 2053 // Otherwise, quad registers are stored with two separate instructions, 2054 // where one stores the even registers and the other stores the odd registers. 2055 2056 // Form the QQQQ REG_SEQUENCE. 2057 SDValue V0 = N->getOperand(Vec0Idx + 0); 2058 SDValue V1 = N->getOperand(Vec0Idx + 1); 2059 SDValue V2 = N->getOperand(Vec0Idx + 2); 2060 SDValue V3 = (NumVecs == 3) 2061 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0) 2062 : N->getOperand(Vec0Idx + 3); 2063 SDValue RegSeq = SDValue(createQuadQRegsNode(MVT::v8i64, V0, V1, V2, V3), 0); 2064 2065 // Store the even D registers. This is always an updating store, so that it 2066 // provides the address to the second store for the odd subregs. 2067 const SDValue OpsA[] = { MemAddr, Align, Reg0, RegSeq, Pred, Reg0, Chain }; 2068 SDNode *VStA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl, 2069 MemAddr.getValueType(), 2070 MVT::Other, OpsA); 2071 cast<MachineSDNode>(VStA)->setMemRefs(MemOp, MemOp + 1); 2072 Chain = SDValue(VStA, 1); 2073 2074 // Store the odd D registers. 2075 Ops.push_back(SDValue(VStA, 0)); 2076 Ops.push_back(Align); 2077 if (isUpdating) { 2078 SDValue Inc = N->getOperand(AddrOpIdx + 1); 2079 assert(isa<ConstantSDNode>(Inc.getNode()) && 2080 "only constant post-increment update allowed for VST3/4"); 2081 (void)Inc; 2082 Ops.push_back(Reg0); 2083 } 2084 Ops.push_back(RegSeq); 2085 Ops.push_back(Pred); 2086 Ops.push_back(Reg0); 2087 Ops.push_back(Chain); 2088 SDNode *VStB = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, 2089 Ops); 2090 cast<MachineSDNode>(VStB)->setMemRefs(MemOp, MemOp + 1); 2091 return VStB; 2092 } 2093 2094 SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad, 2095 bool isUpdating, unsigned NumVecs, 2096 const uint16_t *DOpcodes, 2097 const uint16_t *QOpcodes) { 2098 assert(NumVecs >=2 && NumVecs <= 4 && "VLDSTLane NumVecs out-of-range"); 2099 SDLoc dl(N); 2100 2101 SDValue MemAddr, Align; 2102 unsigned AddrOpIdx = isUpdating ? 1 : 2; 2103 unsigned Vec0Idx = 3; // AddrOpIdx + (isUpdating ? 2 : 1) 2104 if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align)) 2105 return nullptr; 2106 2107 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 2108 MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 2109 2110 SDValue Chain = N->getOperand(0); 2111 unsigned Lane = 2112 cast<ConstantSDNode>(N->getOperand(Vec0Idx + NumVecs))->getZExtValue(); 2113 EVT VT = N->getOperand(Vec0Idx).getValueType(); 2114 bool is64BitVector = VT.is64BitVector(); 2115 2116 unsigned Alignment = 0; 2117 if (NumVecs != 3) { 2118 Alignment = cast<ConstantSDNode>(Align)->getZExtValue(); 2119 unsigned NumBytes = NumVecs * VT.getVectorElementType().getSizeInBits()/8; 2120 if (Alignment > NumBytes) 2121 Alignment = NumBytes; 2122 if (Alignment < 8 && Alignment < NumBytes) 2123 Alignment = 0; 2124 // Alignment must be a power of two; make sure of that. 2125 Alignment = (Alignment & -Alignment); 2126 if (Alignment == 1) 2127 Alignment = 0; 2128 } 2129 Align = CurDAG->getTargetConstant(Alignment, dl, MVT::i32); 2130 2131 unsigned OpcodeIndex; 2132 switch (VT.getSimpleVT().SimpleTy) { 2133 default: llvm_unreachable("unhandled vld/vst lane type"); 2134 // Double-register operations: 2135 case MVT::v8i8: OpcodeIndex = 0; break; 2136 case MVT::v4i16: OpcodeIndex = 1; break; 2137 case MVT::v2f32: 2138 case MVT::v2i32: OpcodeIndex = 2; break; 2139 // Quad-register operations: 2140 case MVT::v8i16: OpcodeIndex = 0; break; 2141 case MVT::v4f32: 2142 case MVT::v4i32: OpcodeIndex = 1; break; 2143 } 2144 2145 std::vector<EVT> ResTys; 2146 if (IsLoad) { 2147 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs; 2148 if (!is64BitVector) 2149 ResTyElts *= 2; 2150 ResTys.push_back(EVT::getVectorVT(*CurDAG->getContext(), 2151 MVT::i64, ResTyElts)); 2152 } 2153 if (isUpdating) 2154 ResTys.push_back(MVT::i32); 2155 ResTys.push_back(MVT::Other); 2156 2157 SDValue Pred = getAL(CurDAG, dl); 2158 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2159 2160 SmallVector<SDValue, 8> Ops; 2161 Ops.push_back(MemAddr); 2162 Ops.push_back(Align); 2163 if (isUpdating) { 2164 SDValue Inc = N->getOperand(AddrOpIdx + 1); 2165 Ops.push_back(isa<ConstantSDNode>(Inc.getNode()) ? Reg0 : Inc); 2166 } 2167 2168 SDValue SuperReg; 2169 SDValue V0 = N->getOperand(Vec0Idx + 0); 2170 SDValue V1 = N->getOperand(Vec0Idx + 1); 2171 if (NumVecs == 2) { 2172 if (is64BitVector) 2173 SuperReg = SDValue(createDRegPairNode(MVT::v2i64, V0, V1), 0); 2174 else 2175 SuperReg = SDValue(createQRegPairNode(MVT::v4i64, V0, V1), 0); 2176 } else { 2177 SDValue V2 = N->getOperand(Vec0Idx + 2); 2178 SDValue V3 = (NumVecs == 3) 2179 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0) 2180 : N->getOperand(Vec0Idx + 3); 2181 if (is64BitVector) 2182 SuperReg = SDValue(createQuadDRegsNode(MVT::v4i64, V0, V1, V2, V3), 0); 2183 else 2184 SuperReg = SDValue(createQuadQRegsNode(MVT::v8i64, V0, V1, V2, V3), 0); 2185 } 2186 Ops.push_back(SuperReg); 2187 Ops.push_back(getI32Imm(Lane, dl)); 2188 Ops.push_back(Pred); 2189 Ops.push_back(Reg0); 2190 Ops.push_back(Chain); 2191 2192 unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] : 2193 QOpcodes[OpcodeIndex]); 2194 SDNode *VLdLn = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 2195 cast<MachineSDNode>(VLdLn)->setMemRefs(MemOp, MemOp + 1); 2196 if (!IsLoad) 2197 return VLdLn; 2198 2199 // Extract the subregisters. 2200 SuperReg = SDValue(VLdLn, 0); 2201 assert(ARM::dsub_7 == ARM::dsub_0+7 && 2202 ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering"); 2203 unsigned Sub0 = is64BitVector ? ARM::dsub_0 : ARM::qsub_0; 2204 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 2205 ReplaceUses(SDValue(N, Vec), 2206 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg)); 2207 ReplaceUses(SDValue(N, NumVecs), SDValue(VLdLn, 1)); 2208 if (isUpdating) 2209 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(VLdLn, 2)); 2210 return nullptr; 2211 } 2212 2213 SDNode *ARMDAGToDAGISel::SelectVLDDup(SDNode *N, bool isUpdating, 2214 unsigned NumVecs, 2215 const uint16_t *Opcodes) { 2216 assert(NumVecs >=2 && NumVecs <= 4 && "VLDDup NumVecs out-of-range"); 2217 SDLoc dl(N); 2218 2219 SDValue MemAddr, Align; 2220 if (!SelectAddrMode6(N, N->getOperand(1), MemAddr, Align)) 2221 return nullptr; 2222 2223 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 2224 MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 2225 2226 SDValue Chain = N->getOperand(0); 2227 EVT VT = N->getValueType(0); 2228 2229 unsigned Alignment = 0; 2230 if (NumVecs != 3) { 2231 Alignment = cast<ConstantSDNode>(Align)->getZExtValue(); 2232 unsigned NumBytes = NumVecs * VT.getVectorElementType().getSizeInBits()/8; 2233 if (Alignment > NumBytes) 2234 Alignment = NumBytes; 2235 if (Alignment < 8 && Alignment < NumBytes) 2236 Alignment = 0; 2237 // Alignment must be a power of two; make sure of that. 2238 Alignment = (Alignment & -Alignment); 2239 if (Alignment == 1) 2240 Alignment = 0; 2241 } 2242 Align = CurDAG->getTargetConstant(Alignment, dl, MVT::i32); 2243 2244 unsigned OpcodeIndex; 2245 switch (VT.getSimpleVT().SimpleTy) { 2246 default: llvm_unreachable("unhandled vld-dup type"); 2247 case MVT::v8i8: OpcodeIndex = 0; break; 2248 case MVT::v4i16: OpcodeIndex = 1; break; 2249 case MVT::v2f32: 2250 case MVT::v2i32: OpcodeIndex = 2; break; 2251 } 2252 2253 SDValue Pred = getAL(CurDAG, dl); 2254 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2255 SDValue SuperReg; 2256 unsigned Opc = Opcodes[OpcodeIndex]; 2257 SmallVector<SDValue, 6> Ops; 2258 Ops.push_back(MemAddr); 2259 Ops.push_back(Align); 2260 if (isUpdating) { 2261 // fixed-stride update instructions don't have an explicit writeback 2262 // operand. It's implicit in the opcode itself. 2263 SDValue Inc = N->getOperand(2); 2264 if (!isa<ConstantSDNode>(Inc.getNode())) 2265 Ops.push_back(Inc); 2266 // FIXME: VLD3 and VLD4 haven't been updated to that form yet. 2267 else if (NumVecs > 2) 2268 Ops.push_back(Reg0); 2269 } 2270 Ops.push_back(Pred); 2271 Ops.push_back(Reg0); 2272 Ops.push_back(Chain); 2273 2274 unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs; 2275 std::vector<EVT> ResTys; 2276 ResTys.push_back(EVT::getVectorVT(*CurDAG->getContext(), MVT::i64,ResTyElts)); 2277 if (isUpdating) 2278 ResTys.push_back(MVT::i32); 2279 ResTys.push_back(MVT::Other); 2280 SDNode *VLdDup = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 2281 cast<MachineSDNode>(VLdDup)->setMemRefs(MemOp, MemOp + 1); 2282 SuperReg = SDValue(VLdDup, 0); 2283 2284 // Extract the subregisters. 2285 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 2286 unsigned SubIdx = ARM::dsub_0; 2287 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 2288 ReplaceUses(SDValue(N, Vec), 2289 CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, SuperReg)); 2290 ReplaceUses(SDValue(N, NumVecs), SDValue(VLdDup, 1)); 2291 if (isUpdating) 2292 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(VLdDup, 2)); 2293 return nullptr; 2294 } 2295 2296 SDNode *ARMDAGToDAGISel::SelectVTBL(SDNode *N, bool IsExt, unsigned NumVecs, 2297 unsigned Opc) { 2298 assert(NumVecs >= 2 && NumVecs <= 4 && "VTBL NumVecs out-of-range"); 2299 SDLoc dl(N); 2300 EVT VT = N->getValueType(0); 2301 unsigned FirstTblReg = IsExt ? 2 : 1; 2302 2303 // Form a REG_SEQUENCE to force register allocation. 2304 SDValue RegSeq; 2305 SDValue V0 = N->getOperand(FirstTblReg + 0); 2306 SDValue V1 = N->getOperand(FirstTblReg + 1); 2307 if (NumVecs == 2) 2308 RegSeq = SDValue(createDRegPairNode(MVT::v16i8, V0, V1), 0); 2309 else { 2310 SDValue V2 = N->getOperand(FirstTblReg + 2); 2311 // If it's a vtbl3, form a quad D-register and leave the last part as 2312 // an undef. 2313 SDValue V3 = (NumVecs == 3) 2314 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0) 2315 : N->getOperand(FirstTblReg + 3); 2316 RegSeq = SDValue(createQuadDRegsNode(MVT::v4i64, V0, V1, V2, V3), 0); 2317 } 2318 2319 SmallVector<SDValue, 6> Ops; 2320 if (IsExt) 2321 Ops.push_back(N->getOperand(1)); 2322 Ops.push_back(RegSeq); 2323 Ops.push_back(N->getOperand(FirstTblReg + NumVecs)); 2324 Ops.push_back(getAL(CurDAG, dl)); // predicate 2325 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // predicate register 2326 return CurDAG->getMachineNode(Opc, dl, VT, Ops); 2327 } 2328 2329 SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N, 2330 bool isSigned) { 2331 if (!Subtarget->hasV6T2Ops()) 2332 return nullptr; 2333 2334 unsigned Opc = isSigned 2335 ? (Subtarget->isThumb() ? ARM::t2SBFX : ARM::SBFX) 2336 : (Subtarget->isThumb() ? ARM::t2UBFX : ARM::UBFX); 2337 SDLoc dl(N); 2338 2339 // For unsigned extracts, check for a shift right and mask 2340 unsigned And_imm = 0; 2341 if (N->getOpcode() == ISD::AND) { 2342 if (isOpcWithIntImmediate(N, ISD::AND, And_imm)) { 2343 2344 // The immediate is a mask of the low bits iff imm & (imm+1) == 0 2345 if (And_imm & (And_imm + 1)) 2346 return nullptr; 2347 2348 unsigned Srl_imm = 0; 2349 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRL, 2350 Srl_imm)) { 2351 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 2352 2353 // Note: The width operand is encoded as width-1. 2354 unsigned Width = countTrailingOnes(And_imm) - 1; 2355 unsigned LSB = Srl_imm; 2356 2357 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2358 2359 if ((LSB + Width + 1) == N->getValueType(0).getSizeInBits()) { 2360 // It's cheaper to use a right shift to extract the top bits. 2361 if (Subtarget->isThumb()) { 2362 Opc = isSigned ? ARM::t2ASRri : ARM::t2LSRri; 2363 SDValue Ops[] = { N->getOperand(0).getOperand(0), 2364 CurDAG->getTargetConstant(LSB, dl, MVT::i32), 2365 getAL(CurDAG, dl), Reg0, Reg0 }; 2366 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2367 } 2368 2369 // ARM models shift instructions as MOVsi with shifter operand. 2370 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(ISD::SRL); 2371 SDValue ShOpc = 2372 CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, LSB), dl, 2373 MVT::i32); 2374 SDValue Ops[] = { N->getOperand(0).getOperand(0), ShOpc, 2375 getAL(CurDAG, dl), Reg0, Reg0 }; 2376 return CurDAG->SelectNodeTo(N, ARM::MOVsi, MVT::i32, Ops); 2377 } 2378 2379 SDValue Ops[] = { N->getOperand(0).getOperand(0), 2380 CurDAG->getTargetConstant(LSB, dl, MVT::i32), 2381 CurDAG->getTargetConstant(Width, dl, MVT::i32), 2382 getAL(CurDAG, dl), Reg0 }; 2383 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2384 } 2385 } 2386 return nullptr; 2387 } 2388 2389 // Otherwise, we're looking for a shift of a shift 2390 unsigned Shl_imm = 0; 2391 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, Shl_imm)) { 2392 assert(Shl_imm > 0 && Shl_imm < 32 && "bad amount in shift node!"); 2393 unsigned Srl_imm = 0; 2394 if (isInt32Immediate(N->getOperand(1), Srl_imm)) { 2395 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 2396 // Note: The width operand is encoded as width-1. 2397 unsigned Width = 32 - Srl_imm - 1; 2398 int LSB = Srl_imm - Shl_imm; 2399 if (LSB < 0) 2400 return nullptr; 2401 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2402 SDValue Ops[] = { N->getOperand(0).getOperand(0), 2403 CurDAG->getTargetConstant(LSB, dl, MVT::i32), 2404 CurDAG->getTargetConstant(Width, dl, MVT::i32), 2405 getAL(CurDAG, dl), Reg0 }; 2406 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2407 } 2408 } 2409 2410 if (N->getOpcode() == ISD::SIGN_EXTEND_INREG) { 2411 unsigned Width = cast<VTSDNode>(N->getOperand(1))->getVT().getSizeInBits(); 2412 unsigned LSB = 0; 2413 if (!isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRL, LSB) && 2414 !isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRA, LSB)) 2415 return nullptr; 2416 2417 if (LSB + Width > 32) 2418 return nullptr; 2419 2420 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2421 SDValue Ops[] = { N->getOperand(0).getOperand(0), 2422 CurDAG->getTargetConstant(LSB, dl, MVT::i32), 2423 CurDAG->getTargetConstant(Width - 1, dl, MVT::i32), 2424 getAL(CurDAG, dl), Reg0 }; 2425 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2426 } 2427 2428 return nullptr; 2429 } 2430 2431 /// Target-specific DAG combining for ISD::XOR. 2432 /// Target-independent combining lowers SELECT_CC nodes of the form 2433 /// select_cc setg[ge] X, 0, X, -X 2434 /// select_cc setgt X, -1, X, -X 2435 /// select_cc setl[te] X, 0, -X, X 2436 /// select_cc setlt X, 1, -X, X 2437 /// which represent Integer ABS into: 2438 /// Y = sra (X, size(X)-1); xor (add (X, Y), Y) 2439 /// ARM instruction selection detects the latter and matches it to 2440 /// ARM::ABS or ARM::t2ABS machine node. 2441 SDNode *ARMDAGToDAGISel::SelectABSOp(SDNode *N){ 2442 SDValue XORSrc0 = N->getOperand(0); 2443 SDValue XORSrc1 = N->getOperand(1); 2444 EVT VT = N->getValueType(0); 2445 2446 if (Subtarget->isThumb1Only()) 2447 return nullptr; 2448 2449 if (XORSrc0.getOpcode() != ISD::ADD || XORSrc1.getOpcode() != ISD::SRA) 2450 return nullptr; 2451 2452 SDValue ADDSrc0 = XORSrc0.getOperand(0); 2453 SDValue ADDSrc1 = XORSrc0.getOperand(1); 2454 SDValue SRASrc0 = XORSrc1.getOperand(0); 2455 SDValue SRASrc1 = XORSrc1.getOperand(1); 2456 ConstantSDNode *SRAConstant = dyn_cast<ConstantSDNode>(SRASrc1); 2457 EVT XType = SRASrc0.getValueType(); 2458 unsigned Size = XType.getSizeInBits() - 1; 2459 2460 if (ADDSrc1 == XORSrc1 && ADDSrc0 == SRASrc0 && 2461 XType.isInteger() && SRAConstant != nullptr && 2462 Size == SRAConstant->getZExtValue()) { 2463 unsigned Opcode = Subtarget->isThumb2() ? ARM::t2ABS : ARM::ABS; 2464 return CurDAG->SelectNodeTo(N, Opcode, VT, ADDSrc0); 2465 } 2466 2467 return nullptr; 2468 } 2469 2470 SDNode *ARMDAGToDAGISel::SelectConcatVector(SDNode *N) { 2471 // The only time a CONCAT_VECTORS operation can have legal types is when 2472 // two 64-bit vectors are concatenated to a 128-bit vector. 2473 EVT VT = N->getValueType(0); 2474 if (!VT.is128BitVector() || N->getNumOperands() != 2) 2475 llvm_unreachable("unexpected CONCAT_VECTORS"); 2476 return createDRegPairNode(VT, N->getOperand(0), N->getOperand(1)); 2477 } 2478 2479 SDNode *ARMDAGToDAGISel::Select(SDNode *N) { 2480 SDLoc dl(N); 2481 2482 if (N->isMachineOpcode()) { 2483 N->setNodeId(-1); 2484 return nullptr; // Already selected. 2485 } 2486 2487 switch (N->getOpcode()) { 2488 default: break; 2489 case ISD::WRITE_REGISTER: { 2490 SDNode *ResNode = SelectWriteRegister(N); 2491 if (ResNode) 2492 return ResNode; 2493 break; 2494 } 2495 case ISD::READ_REGISTER: { 2496 SDNode *ResNode = SelectReadRegister(N); 2497 if (ResNode) 2498 return ResNode; 2499 break; 2500 } 2501 case ISD::INLINEASM: { 2502 SDNode *ResNode = SelectInlineAsm(N); 2503 if (ResNode) 2504 return ResNode; 2505 break; 2506 } 2507 case ISD::XOR: { 2508 // Select special operations if XOR node forms integer ABS pattern 2509 SDNode *ResNode = SelectABSOp(N); 2510 if (ResNode) 2511 return ResNode; 2512 // Other cases are autogenerated. 2513 break; 2514 } 2515 case ISD::Constant: { 2516 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 2517 // If we can't materialize the constant we need to use a literal pool 2518 if (ConstantMaterializationCost(Val) > 2) { 2519 SDValue CPIdx = CurDAG->getTargetConstantPool( 2520 ConstantInt::get(Type::getInt32Ty(*CurDAG->getContext()), Val), 2521 TLI->getPointerTy(CurDAG->getDataLayout())); 2522 2523 SDNode *ResNode; 2524 if (Subtarget->isThumb()) { 2525 SDValue Pred = getAL(CurDAG, dl); 2526 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 2527 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() }; 2528 ResNode = CurDAG->getMachineNode(ARM::tLDRpci, dl, MVT::i32, MVT::Other, 2529 Ops); 2530 } else { 2531 SDValue Ops[] = { 2532 CPIdx, 2533 CurDAG->getTargetConstant(0, dl, MVT::i32), 2534 getAL(CurDAG, dl), 2535 CurDAG->getRegister(0, MVT::i32), 2536 CurDAG->getEntryNode() 2537 }; 2538 ResNode=CurDAG->getMachineNode(ARM::LDRcp, dl, MVT::i32, MVT::Other, 2539 Ops); 2540 } 2541 ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0)); 2542 return nullptr; 2543 } 2544 2545 // Other cases are autogenerated. 2546 break; 2547 } 2548 case ISD::FrameIndex: { 2549 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. 2550 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 2551 SDValue TFI = CurDAG->getTargetFrameIndex( 2552 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 2553 if (Subtarget->isThumb1Only()) { 2554 // Set the alignment of the frame object to 4, to avoid having to generate 2555 // more than one ADD 2556 MachineFrameInfo *MFI = MF->getFrameInfo(); 2557 if (MFI->getObjectAlignment(FI) < 4) 2558 MFI->setObjectAlignment(FI, 4); 2559 return CurDAG->SelectNodeTo(N, ARM::tADDframe, MVT::i32, TFI, 2560 CurDAG->getTargetConstant(0, dl, MVT::i32)); 2561 } else { 2562 unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ? 2563 ARM::t2ADDri : ARM::ADDri); 2564 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, dl, MVT::i32), 2565 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32), 2566 CurDAG->getRegister(0, MVT::i32) }; 2567 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops); 2568 } 2569 } 2570 case ISD::SRL: 2571 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, false)) 2572 return I; 2573 break; 2574 case ISD::SIGN_EXTEND_INREG: 2575 case ISD::SRA: 2576 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, true)) 2577 return I; 2578 break; 2579 case ISD::MUL: 2580 if (Subtarget->isThumb1Only()) 2581 break; 2582 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) { 2583 unsigned RHSV = C->getZExtValue(); 2584 if (!RHSV) break; 2585 if (isPowerOf2_32(RHSV-1)) { // 2^n+1? 2586 unsigned ShImm = Log2_32(RHSV-1); 2587 if (ShImm >= 32) 2588 break; 2589 SDValue V = N->getOperand(0); 2590 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 2591 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, dl, MVT::i32); 2592 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2593 if (Subtarget->isThumb()) { 2594 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG, dl), Reg0, Reg0 }; 2595 return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops); 2596 } else { 2597 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG, dl), Reg0, 2598 Reg0 }; 2599 return CurDAG->SelectNodeTo(N, ARM::ADDrsi, MVT::i32, Ops); 2600 } 2601 } 2602 if (isPowerOf2_32(RHSV+1)) { // 2^n-1? 2603 unsigned ShImm = Log2_32(RHSV+1); 2604 if (ShImm >= 32) 2605 break; 2606 SDValue V = N->getOperand(0); 2607 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 2608 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, dl, MVT::i32); 2609 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 2610 if (Subtarget->isThumb()) { 2611 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG, dl), Reg0, Reg0 }; 2612 return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops); 2613 } else { 2614 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG, dl), Reg0, 2615 Reg0 }; 2616 return CurDAG->SelectNodeTo(N, ARM::RSBrsi, MVT::i32, Ops); 2617 } 2618 } 2619 } 2620 break; 2621 case ISD::AND: { 2622 // Check for unsigned bitfield extract 2623 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, false)) 2624 return I; 2625 2626 // (and (or x, c2), c1) and top 16-bits of c1 and c2 match, lower 16-bits 2627 // of c1 are 0xffff, and lower 16-bit of c2 are 0. That is, the top 16-bits 2628 // are entirely contributed by c2 and lower 16-bits are entirely contributed 2629 // by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)). 2630 // Select it to: "movt x, ((c1 & 0xffff) >> 16) 2631 EVT VT = N->getValueType(0); 2632 if (VT != MVT::i32) 2633 break; 2634 unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2()) 2635 ? ARM::t2MOVTi16 2636 : (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0); 2637 if (!Opc) 2638 break; 2639 SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); 2640 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 2641 if (!N1C) 2642 break; 2643 if (N0.getOpcode() == ISD::OR && N0.getNode()->hasOneUse()) { 2644 SDValue N2 = N0.getOperand(1); 2645 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2); 2646 if (!N2C) 2647 break; 2648 unsigned N1CVal = N1C->getZExtValue(); 2649 unsigned N2CVal = N2C->getZExtValue(); 2650 if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) && 2651 (N1CVal & 0xffffU) == 0xffffU && 2652 (N2CVal & 0xffffU) == 0x0U) { 2653 SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16, 2654 dl, MVT::i32); 2655 SDValue Ops[] = { N0.getOperand(0), Imm16, 2656 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32) }; 2657 return CurDAG->getMachineNode(Opc, dl, VT, Ops); 2658 } 2659 } 2660 break; 2661 } 2662 case ARMISD::VMOVRRD: 2663 return CurDAG->getMachineNode(ARM::VMOVRRD, dl, MVT::i32, MVT::i32, 2664 N->getOperand(0), getAL(CurDAG, dl), 2665 CurDAG->getRegister(0, MVT::i32)); 2666 case ISD::UMUL_LOHI: { 2667 if (Subtarget->isThumb1Only()) 2668 break; 2669 if (Subtarget->isThumb()) { 2670 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 2671 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32) }; 2672 return CurDAG->getMachineNode(ARM::t2UMULL, dl, MVT::i32, MVT::i32, Ops); 2673 } else { 2674 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 2675 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32), 2676 CurDAG->getRegister(0, MVT::i32) }; 2677 return CurDAG->getMachineNode(Subtarget->hasV6Ops() ? 2678 ARM::UMULL : ARM::UMULLv5, 2679 dl, MVT::i32, MVT::i32, Ops); 2680 } 2681 } 2682 case ISD::SMUL_LOHI: { 2683 if (Subtarget->isThumb1Only()) 2684 break; 2685 if (Subtarget->isThumb()) { 2686 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 2687 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32) }; 2688 return CurDAG->getMachineNode(ARM::t2SMULL, dl, MVT::i32, MVT::i32, Ops); 2689 } else { 2690 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 2691 getAL(CurDAG, dl), CurDAG->getRegister(0, MVT::i32), 2692 CurDAG->getRegister(0, MVT::i32) }; 2693 return CurDAG->getMachineNode(Subtarget->hasV6Ops() ? 2694 ARM::SMULL : ARM::SMULLv5, 2695 dl, MVT::i32, MVT::i32, Ops); 2696 } 2697 } 2698 case ARMISD::UMLAL:{ 2699 if (Subtarget->isThumb()) { 2700 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), 2701 N->getOperand(3), getAL(CurDAG, dl), 2702 CurDAG->getRegister(0, MVT::i32)}; 2703 return CurDAG->getMachineNode(ARM::t2UMLAL, dl, MVT::i32, MVT::i32, Ops); 2704 }else{ 2705 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), 2706 N->getOperand(3), getAL(CurDAG, dl), 2707 CurDAG->getRegister(0, MVT::i32), 2708 CurDAG->getRegister(0, MVT::i32) }; 2709 return CurDAG->getMachineNode(Subtarget->hasV6Ops() ? 2710 ARM::UMLAL : ARM::UMLALv5, 2711 dl, MVT::i32, MVT::i32, Ops); 2712 } 2713 } 2714 case ARMISD::SMLAL:{ 2715 if (Subtarget->isThumb()) { 2716 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), 2717 N->getOperand(3), getAL(CurDAG, dl), 2718 CurDAG->getRegister(0, MVT::i32)}; 2719 return CurDAG->getMachineNode(ARM::t2SMLAL, dl, MVT::i32, MVT::i32, Ops); 2720 }else{ 2721 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2), 2722 N->getOperand(3), getAL(CurDAG, dl), 2723 CurDAG->getRegister(0, MVT::i32), 2724 CurDAG->getRegister(0, MVT::i32) }; 2725 return CurDAG->getMachineNode(Subtarget->hasV6Ops() ? 2726 ARM::SMLAL : ARM::SMLALv5, 2727 dl, MVT::i32, MVT::i32, Ops); 2728 } 2729 } 2730 case ISD::LOAD: { 2731 SDNode *ResNode = nullptr; 2732 if (Subtarget->isThumb() && Subtarget->hasThumb2()) 2733 ResNode = SelectT2IndexedLoad(N); 2734 else 2735 ResNode = SelectARMIndexedLoad(N); 2736 if (ResNode) 2737 return ResNode; 2738 // Other cases are autogenerated. 2739 break; 2740 } 2741 case ARMISD::BRCOND: { 2742 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 2743 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc) 2744 // Pattern complexity = 6 cost = 1 size = 0 2745 2746 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 2747 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc) 2748 // Pattern complexity = 6 cost = 1 size = 0 2749 2750 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 2751 // Emits: (t2Bcc:void (bb:Other):$dst, (imm:i32):$cc) 2752 // Pattern complexity = 6 cost = 1 size = 0 2753 2754 unsigned Opc = Subtarget->isThumb() ? 2755 ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; 2756 SDValue Chain = N->getOperand(0); 2757 SDValue N1 = N->getOperand(1); 2758 SDValue N2 = N->getOperand(2); 2759 SDValue N3 = N->getOperand(3); 2760 SDValue InFlag = N->getOperand(4); 2761 assert(N1.getOpcode() == ISD::BasicBlock); 2762 assert(N2.getOpcode() == ISD::Constant); 2763 assert(N3.getOpcode() == ISD::Register); 2764 2765 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 2766 cast<ConstantSDNode>(N2)->getZExtValue()), dl, 2767 MVT::i32); 2768 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; 2769 SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, 2770 MVT::Glue, Ops); 2771 Chain = SDValue(ResNode, 0); 2772 if (N->getNumValues() == 2) { 2773 InFlag = SDValue(ResNode, 1); 2774 ReplaceUses(SDValue(N, 1), InFlag); 2775 } 2776 ReplaceUses(SDValue(N, 0), 2777 SDValue(Chain.getNode(), Chain.getResNo())); 2778 return nullptr; 2779 } 2780 case ARMISD::VZIP: { 2781 unsigned Opc = 0; 2782 EVT VT = N->getValueType(0); 2783 switch (VT.getSimpleVT().SimpleTy) { 2784 default: return nullptr; 2785 case MVT::v8i8: Opc = ARM::VZIPd8; break; 2786 case MVT::v4i16: Opc = ARM::VZIPd16; break; 2787 case MVT::v2f32: 2788 // vzip.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm. 2789 case MVT::v2i32: Opc = ARM::VTRNd32; break; 2790 case MVT::v16i8: Opc = ARM::VZIPq8; break; 2791 case MVT::v8i16: Opc = ARM::VZIPq16; break; 2792 case MVT::v4f32: 2793 case MVT::v4i32: Opc = ARM::VZIPq32; break; 2794 } 2795 SDValue Pred = getAL(CurDAG, dl); 2796 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 2797 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 2798 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops); 2799 } 2800 case ARMISD::VUZP: { 2801 unsigned Opc = 0; 2802 EVT VT = N->getValueType(0); 2803 switch (VT.getSimpleVT().SimpleTy) { 2804 default: return nullptr; 2805 case MVT::v8i8: Opc = ARM::VUZPd8; break; 2806 case MVT::v4i16: Opc = ARM::VUZPd16; break; 2807 case MVT::v2f32: 2808 // vuzp.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm. 2809 case MVT::v2i32: Opc = ARM::VTRNd32; break; 2810 case MVT::v16i8: Opc = ARM::VUZPq8; break; 2811 case MVT::v8i16: Opc = ARM::VUZPq16; break; 2812 case MVT::v4f32: 2813 case MVT::v4i32: Opc = ARM::VUZPq32; break; 2814 } 2815 SDValue Pred = getAL(CurDAG, dl); 2816 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 2817 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 2818 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops); 2819 } 2820 case ARMISD::VTRN: { 2821 unsigned Opc = 0; 2822 EVT VT = N->getValueType(0); 2823 switch (VT.getSimpleVT().SimpleTy) { 2824 default: return nullptr; 2825 case MVT::v8i8: Opc = ARM::VTRNd8; break; 2826 case MVT::v4i16: Opc = ARM::VTRNd16; break; 2827 case MVT::v2f32: 2828 case MVT::v2i32: Opc = ARM::VTRNd32; break; 2829 case MVT::v16i8: Opc = ARM::VTRNq8; break; 2830 case MVT::v8i16: Opc = ARM::VTRNq16; break; 2831 case MVT::v4f32: 2832 case MVT::v4i32: Opc = ARM::VTRNq32; break; 2833 } 2834 SDValue Pred = getAL(CurDAG, dl); 2835 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 2836 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 2837 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops); 2838 } 2839 case ARMISD::BUILD_VECTOR: { 2840 EVT VecVT = N->getValueType(0); 2841 EVT EltVT = VecVT.getVectorElementType(); 2842 unsigned NumElts = VecVT.getVectorNumElements(); 2843 if (EltVT == MVT::f64) { 2844 assert(NumElts == 2 && "unexpected type for BUILD_VECTOR"); 2845 return createDRegPairNode(VecVT, N->getOperand(0), N->getOperand(1)); 2846 } 2847 assert(EltVT == MVT::f32 && "unexpected type for BUILD_VECTOR"); 2848 if (NumElts == 2) 2849 return createSRegPairNode(VecVT, N->getOperand(0), N->getOperand(1)); 2850 assert(NumElts == 4 && "unexpected type for BUILD_VECTOR"); 2851 return createQuadSRegsNode(VecVT, N->getOperand(0), N->getOperand(1), 2852 N->getOperand(2), N->getOperand(3)); 2853 } 2854 2855 case ARMISD::VLD2DUP: { 2856 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8, ARM::VLD2DUPd16, 2857 ARM::VLD2DUPd32 }; 2858 return SelectVLDDup(N, false, 2, Opcodes); 2859 } 2860 2861 case ARMISD::VLD3DUP: { 2862 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo, 2863 ARM::VLD3DUPd16Pseudo, 2864 ARM::VLD3DUPd32Pseudo }; 2865 return SelectVLDDup(N, false, 3, Opcodes); 2866 } 2867 2868 case ARMISD::VLD4DUP: { 2869 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo, 2870 ARM::VLD4DUPd16Pseudo, 2871 ARM::VLD4DUPd32Pseudo }; 2872 return SelectVLDDup(N, false, 4, Opcodes); 2873 } 2874 2875 case ARMISD::VLD2DUP_UPD: { 2876 static const uint16_t Opcodes[] = { ARM::VLD2DUPd8wb_fixed, 2877 ARM::VLD2DUPd16wb_fixed, 2878 ARM::VLD2DUPd32wb_fixed }; 2879 return SelectVLDDup(N, true, 2, Opcodes); 2880 } 2881 2882 case ARMISD::VLD3DUP_UPD: { 2883 static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo_UPD, 2884 ARM::VLD3DUPd16Pseudo_UPD, 2885 ARM::VLD3DUPd32Pseudo_UPD }; 2886 return SelectVLDDup(N, true, 3, Opcodes); 2887 } 2888 2889 case ARMISD::VLD4DUP_UPD: { 2890 static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo_UPD, 2891 ARM::VLD4DUPd16Pseudo_UPD, 2892 ARM::VLD4DUPd32Pseudo_UPD }; 2893 return SelectVLDDup(N, true, 4, Opcodes); 2894 } 2895 2896 case ARMISD::VLD1_UPD: { 2897 static const uint16_t DOpcodes[] = { ARM::VLD1d8wb_fixed, 2898 ARM::VLD1d16wb_fixed, 2899 ARM::VLD1d32wb_fixed, 2900 ARM::VLD1d64wb_fixed }; 2901 static const uint16_t QOpcodes[] = { ARM::VLD1q8wb_fixed, 2902 ARM::VLD1q16wb_fixed, 2903 ARM::VLD1q32wb_fixed, 2904 ARM::VLD1q64wb_fixed }; 2905 return SelectVLD(N, true, 1, DOpcodes, QOpcodes, nullptr); 2906 } 2907 2908 case ARMISD::VLD2_UPD: { 2909 static const uint16_t DOpcodes[] = { ARM::VLD2d8wb_fixed, 2910 ARM::VLD2d16wb_fixed, 2911 ARM::VLD2d32wb_fixed, 2912 ARM::VLD1q64wb_fixed}; 2913 static const uint16_t QOpcodes[] = { ARM::VLD2q8PseudoWB_fixed, 2914 ARM::VLD2q16PseudoWB_fixed, 2915 ARM::VLD2q32PseudoWB_fixed }; 2916 return SelectVLD(N, true, 2, DOpcodes, QOpcodes, nullptr); 2917 } 2918 2919 case ARMISD::VLD3_UPD: { 2920 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo_UPD, 2921 ARM::VLD3d16Pseudo_UPD, 2922 ARM::VLD3d32Pseudo_UPD, 2923 ARM::VLD1d64TPseudoWB_fixed}; 2924 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD, 2925 ARM::VLD3q16Pseudo_UPD, 2926 ARM::VLD3q32Pseudo_UPD }; 2927 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo_UPD, 2928 ARM::VLD3q16oddPseudo_UPD, 2929 ARM::VLD3q32oddPseudo_UPD }; 2930 return SelectVLD(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1); 2931 } 2932 2933 case ARMISD::VLD4_UPD: { 2934 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo_UPD, 2935 ARM::VLD4d16Pseudo_UPD, 2936 ARM::VLD4d32Pseudo_UPD, 2937 ARM::VLD1d64QPseudoWB_fixed}; 2938 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD, 2939 ARM::VLD4q16Pseudo_UPD, 2940 ARM::VLD4q32Pseudo_UPD }; 2941 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo_UPD, 2942 ARM::VLD4q16oddPseudo_UPD, 2943 ARM::VLD4q32oddPseudo_UPD }; 2944 return SelectVLD(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1); 2945 } 2946 2947 case ARMISD::VLD2LN_UPD: { 2948 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo_UPD, 2949 ARM::VLD2LNd16Pseudo_UPD, 2950 ARM::VLD2LNd32Pseudo_UPD }; 2951 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo_UPD, 2952 ARM::VLD2LNq32Pseudo_UPD }; 2953 return SelectVLDSTLane(N, true, true, 2, DOpcodes, QOpcodes); 2954 } 2955 2956 case ARMISD::VLD3LN_UPD: { 2957 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo_UPD, 2958 ARM::VLD3LNd16Pseudo_UPD, 2959 ARM::VLD3LNd32Pseudo_UPD }; 2960 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo_UPD, 2961 ARM::VLD3LNq32Pseudo_UPD }; 2962 return SelectVLDSTLane(N, true, true, 3, DOpcodes, QOpcodes); 2963 } 2964 2965 case ARMISD::VLD4LN_UPD: { 2966 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo_UPD, 2967 ARM::VLD4LNd16Pseudo_UPD, 2968 ARM::VLD4LNd32Pseudo_UPD }; 2969 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo_UPD, 2970 ARM::VLD4LNq32Pseudo_UPD }; 2971 return SelectVLDSTLane(N, true, true, 4, DOpcodes, QOpcodes); 2972 } 2973 2974 case ARMISD::VST1_UPD: { 2975 static const uint16_t DOpcodes[] = { ARM::VST1d8wb_fixed, 2976 ARM::VST1d16wb_fixed, 2977 ARM::VST1d32wb_fixed, 2978 ARM::VST1d64wb_fixed }; 2979 static const uint16_t QOpcodes[] = { ARM::VST1q8wb_fixed, 2980 ARM::VST1q16wb_fixed, 2981 ARM::VST1q32wb_fixed, 2982 ARM::VST1q64wb_fixed }; 2983 return SelectVST(N, true, 1, DOpcodes, QOpcodes, nullptr); 2984 } 2985 2986 case ARMISD::VST2_UPD: { 2987 static const uint16_t DOpcodes[] = { ARM::VST2d8wb_fixed, 2988 ARM::VST2d16wb_fixed, 2989 ARM::VST2d32wb_fixed, 2990 ARM::VST1q64wb_fixed}; 2991 static const uint16_t QOpcodes[] = { ARM::VST2q8PseudoWB_fixed, 2992 ARM::VST2q16PseudoWB_fixed, 2993 ARM::VST2q32PseudoWB_fixed }; 2994 return SelectVST(N, true, 2, DOpcodes, QOpcodes, nullptr); 2995 } 2996 2997 case ARMISD::VST3_UPD: { 2998 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo_UPD, 2999 ARM::VST3d16Pseudo_UPD, 3000 ARM::VST3d32Pseudo_UPD, 3001 ARM::VST1d64TPseudoWB_fixed}; 3002 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD, 3003 ARM::VST3q16Pseudo_UPD, 3004 ARM::VST3q32Pseudo_UPD }; 3005 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo_UPD, 3006 ARM::VST3q16oddPseudo_UPD, 3007 ARM::VST3q32oddPseudo_UPD }; 3008 return SelectVST(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1); 3009 } 3010 3011 case ARMISD::VST4_UPD: { 3012 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo_UPD, 3013 ARM::VST4d16Pseudo_UPD, 3014 ARM::VST4d32Pseudo_UPD, 3015 ARM::VST1d64QPseudoWB_fixed}; 3016 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD, 3017 ARM::VST4q16Pseudo_UPD, 3018 ARM::VST4q32Pseudo_UPD }; 3019 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo_UPD, 3020 ARM::VST4q16oddPseudo_UPD, 3021 ARM::VST4q32oddPseudo_UPD }; 3022 return SelectVST(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1); 3023 } 3024 3025 case ARMISD::VST2LN_UPD: { 3026 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo_UPD, 3027 ARM::VST2LNd16Pseudo_UPD, 3028 ARM::VST2LNd32Pseudo_UPD }; 3029 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo_UPD, 3030 ARM::VST2LNq32Pseudo_UPD }; 3031 return SelectVLDSTLane(N, false, true, 2, DOpcodes, QOpcodes); 3032 } 3033 3034 case ARMISD::VST3LN_UPD: { 3035 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo_UPD, 3036 ARM::VST3LNd16Pseudo_UPD, 3037 ARM::VST3LNd32Pseudo_UPD }; 3038 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo_UPD, 3039 ARM::VST3LNq32Pseudo_UPD }; 3040 return SelectVLDSTLane(N, false, true, 3, DOpcodes, QOpcodes); 3041 } 3042 3043 case ARMISD::VST4LN_UPD: { 3044 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo_UPD, 3045 ARM::VST4LNd16Pseudo_UPD, 3046 ARM::VST4LNd32Pseudo_UPD }; 3047 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo_UPD, 3048 ARM::VST4LNq32Pseudo_UPD }; 3049 return SelectVLDSTLane(N, false, true, 4, DOpcodes, QOpcodes); 3050 } 3051 3052 case ISD::INTRINSIC_VOID: 3053 case ISD::INTRINSIC_W_CHAIN: { 3054 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 3055 switch (IntNo) { 3056 default: 3057 break; 3058 3059 case Intrinsic::arm_ldaexd: 3060 case Intrinsic::arm_ldrexd: { 3061 SDLoc dl(N); 3062 SDValue Chain = N->getOperand(0); 3063 SDValue MemAddr = N->getOperand(2); 3064 bool isThumb = Subtarget->isThumb() && Subtarget->hasV8MBaselineOps(); 3065 3066 bool IsAcquire = IntNo == Intrinsic::arm_ldaexd; 3067 unsigned NewOpc = isThumb ? (IsAcquire ? ARM::t2LDAEXD : ARM::t2LDREXD) 3068 : (IsAcquire ? ARM::LDAEXD : ARM::LDREXD); 3069 3070 // arm_ldrexd returns a i64 value in {i32, i32} 3071 std::vector<EVT> ResTys; 3072 if (isThumb) { 3073 ResTys.push_back(MVT::i32); 3074 ResTys.push_back(MVT::i32); 3075 } else 3076 ResTys.push_back(MVT::Untyped); 3077 ResTys.push_back(MVT::Other); 3078 3079 // Place arguments in the right order. 3080 SmallVector<SDValue, 7> Ops; 3081 Ops.push_back(MemAddr); 3082 Ops.push_back(getAL(CurDAG, dl)); 3083 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 3084 Ops.push_back(Chain); 3085 SDNode *Ld = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops); 3086 // Transfer memoperands. 3087 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 3088 MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 3089 cast<MachineSDNode>(Ld)->setMemRefs(MemOp, MemOp + 1); 3090 3091 // Remap uses. 3092 SDValue OutChain = isThumb ? SDValue(Ld, 2) : SDValue(Ld, 1); 3093 if (!SDValue(N, 0).use_empty()) { 3094 SDValue Result; 3095 if (isThumb) 3096 Result = SDValue(Ld, 0); 3097 else { 3098 SDValue SubRegIdx = 3099 CurDAG->getTargetConstant(ARM::gsub_0, dl, MVT::i32); 3100 SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 3101 dl, MVT::i32, SDValue(Ld, 0), SubRegIdx); 3102 Result = SDValue(ResNode,0); 3103 } 3104 ReplaceUses(SDValue(N, 0), Result); 3105 } 3106 if (!SDValue(N, 1).use_empty()) { 3107 SDValue Result; 3108 if (isThumb) 3109 Result = SDValue(Ld, 1); 3110 else { 3111 SDValue SubRegIdx = 3112 CurDAG->getTargetConstant(ARM::gsub_1, dl, MVT::i32); 3113 SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 3114 dl, MVT::i32, SDValue(Ld, 0), SubRegIdx); 3115 Result = SDValue(ResNode,0); 3116 } 3117 ReplaceUses(SDValue(N, 1), Result); 3118 } 3119 ReplaceUses(SDValue(N, 2), OutChain); 3120 return nullptr; 3121 } 3122 case Intrinsic::arm_stlexd: 3123 case Intrinsic::arm_strexd: { 3124 SDLoc dl(N); 3125 SDValue Chain = N->getOperand(0); 3126 SDValue Val0 = N->getOperand(2); 3127 SDValue Val1 = N->getOperand(3); 3128 SDValue MemAddr = N->getOperand(4); 3129 3130 // Store exclusive double return a i32 value which is the return status 3131 // of the issued store. 3132 const EVT ResTys[] = {MVT::i32, MVT::Other}; 3133 3134 bool isThumb = Subtarget->isThumb() && Subtarget->hasThumb2(); 3135 // Place arguments in the right order. 3136 SmallVector<SDValue, 7> Ops; 3137 if (isThumb) { 3138 Ops.push_back(Val0); 3139 Ops.push_back(Val1); 3140 } else 3141 // arm_strexd uses GPRPair. 3142 Ops.push_back(SDValue(createGPRPairNode(MVT::Untyped, Val0, Val1), 0)); 3143 Ops.push_back(MemAddr); 3144 Ops.push_back(getAL(CurDAG, dl)); 3145 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 3146 Ops.push_back(Chain); 3147 3148 bool IsRelease = IntNo == Intrinsic::arm_stlexd; 3149 unsigned NewOpc = isThumb ? (IsRelease ? ARM::t2STLEXD : ARM::t2STREXD) 3150 : (IsRelease ? ARM::STLEXD : ARM::STREXD); 3151 3152 SDNode *St = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops); 3153 // Transfer memoperands. 3154 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 3155 MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 3156 cast<MachineSDNode>(St)->setMemRefs(MemOp, MemOp + 1); 3157 3158 return St; 3159 } 3160 3161 case Intrinsic::arm_neon_vld1: { 3162 static const uint16_t DOpcodes[] = { ARM::VLD1d8, ARM::VLD1d16, 3163 ARM::VLD1d32, ARM::VLD1d64 }; 3164 static const uint16_t QOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16, 3165 ARM::VLD1q32, ARM::VLD1q64}; 3166 return SelectVLD(N, false, 1, DOpcodes, QOpcodes, nullptr); 3167 } 3168 3169 case Intrinsic::arm_neon_vld2: { 3170 static const uint16_t DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16, 3171 ARM::VLD2d32, ARM::VLD1q64 }; 3172 static const uint16_t QOpcodes[] = { ARM::VLD2q8Pseudo, ARM::VLD2q16Pseudo, 3173 ARM::VLD2q32Pseudo }; 3174 return SelectVLD(N, false, 2, DOpcodes, QOpcodes, nullptr); 3175 } 3176 3177 case Intrinsic::arm_neon_vld3: { 3178 static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo, 3179 ARM::VLD3d16Pseudo, 3180 ARM::VLD3d32Pseudo, 3181 ARM::VLD1d64TPseudo }; 3182 static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD, 3183 ARM::VLD3q16Pseudo_UPD, 3184 ARM::VLD3q32Pseudo_UPD }; 3185 static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo, 3186 ARM::VLD3q16oddPseudo, 3187 ARM::VLD3q32oddPseudo }; 3188 return SelectVLD(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); 3189 } 3190 3191 case Intrinsic::arm_neon_vld4: { 3192 static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo, 3193 ARM::VLD4d16Pseudo, 3194 ARM::VLD4d32Pseudo, 3195 ARM::VLD1d64QPseudo }; 3196 static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD, 3197 ARM::VLD4q16Pseudo_UPD, 3198 ARM::VLD4q32Pseudo_UPD }; 3199 static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo, 3200 ARM::VLD4q16oddPseudo, 3201 ARM::VLD4q32oddPseudo }; 3202 return SelectVLD(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); 3203 } 3204 3205 case Intrinsic::arm_neon_vld2lane: { 3206 static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo, 3207 ARM::VLD2LNd16Pseudo, 3208 ARM::VLD2LNd32Pseudo }; 3209 static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo, 3210 ARM::VLD2LNq32Pseudo }; 3211 return SelectVLDSTLane(N, true, false, 2, DOpcodes, QOpcodes); 3212 } 3213 3214 case Intrinsic::arm_neon_vld3lane: { 3215 static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo, 3216 ARM::VLD3LNd16Pseudo, 3217 ARM::VLD3LNd32Pseudo }; 3218 static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo, 3219 ARM::VLD3LNq32Pseudo }; 3220 return SelectVLDSTLane(N, true, false, 3, DOpcodes, QOpcodes); 3221 } 3222 3223 case Intrinsic::arm_neon_vld4lane: { 3224 static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo, 3225 ARM::VLD4LNd16Pseudo, 3226 ARM::VLD4LNd32Pseudo }; 3227 static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo, 3228 ARM::VLD4LNq32Pseudo }; 3229 return SelectVLDSTLane(N, true, false, 4, DOpcodes, QOpcodes); 3230 } 3231 3232 case Intrinsic::arm_neon_vst1: { 3233 static const uint16_t DOpcodes[] = { ARM::VST1d8, ARM::VST1d16, 3234 ARM::VST1d32, ARM::VST1d64 }; 3235 static const uint16_t QOpcodes[] = { ARM::VST1q8, ARM::VST1q16, 3236 ARM::VST1q32, ARM::VST1q64 }; 3237 return SelectVST(N, false, 1, DOpcodes, QOpcodes, nullptr); 3238 } 3239 3240 case Intrinsic::arm_neon_vst2: { 3241 static const uint16_t DOpcodes[] = { ARM::VST2d8, ARM::VST2d16, 3242 ARM::VST2d32, ARM::VST1q64 }; 3243 static uint16_t QOpcodes[] = { ARM::VST2q8Pseudo, ARM::VST2q16Pseudo, 3244 ARM::VST2q32Pseudo }; 3245 return SelectVST(N, false, 2, DOpcodes, QOpcodes, nullptr); 3246 } 3247 3248 case Intrinsic::arm_neon_vst3: { 3249 static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo, 3250 ARM::VST3d16Pseudo, 3251 ARM::VST3d32Pseudo, 3252 ARM::VST1d64TPseudo }; 3253 static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD, 3254 ARM::VST3q16Pseudo_UPD, 3255 ARM::VST3q32Pseudo_UPD }; 3256 static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo, 3257 ARM::VST3q16oddPseudo, 3258 ARM::VST3q32oddPseudo }; 3259 return SelectVST(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); 3260 } 3261 3262 case Intrinsic::arm_neon_vst4: { 3263 static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo, 3264 ARM::VST4d16Pseudo, 3265 ARM::VST4d32Pseudo, 3266 ARM::VST1d64QPseudo }; 3267 static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD, 3268 ARM::VST4q16Pseudo_UPD, 3269 ARM::VST4q32Pseudo_UPD }; 3270 static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo, 3271 ARM::VST4q16oddPseudo, 3272 ARM::VST4q32oddPseudo }; 3273 return SelectVST(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); 3274 } 3275 3276 case Intrinsic::arm_neon_vst2lane: { 3277 static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo, 3278 ARM::VST2LNd16Pseudo, 3279 ARM::VST2LNd32Pseudo }; 3280 static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo, 3281 ARM::VST2LNq32Pseudo }; 3282 return SelectVLDSTLane(N, false, false, 2, DOpcodes, QOpcodes); 3283 } 3284 3285 case Intrinsic::arm_neon_vst3lane: { 3286 static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo, 3287 ARM::VST3LNd16Pseudo, 3288 ARM::VST3LNd32Pseudo }; 3289 static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo, 3290 ARM::VST3LNq32Pseudo }; 3291 return SelectVLDSTLane(N, false, false, 3, DOpcodes, QOpcodes); 3292 } 3293 3294 case Intrinsic::arm_neon_vst4lane: { 3295 static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo, 3296 ARM::VST4LNd16Pseudo, 3297 ARM::VST4LNd32Pseudo }; 3298 static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo, 3299 ARM::VST4LNq32Pseudo }; 3300 return SelectVLDSTLane(N, false, false, 4, DOpcodes, QOpcodes); 3301 } 3302 } 3303 break; 3304 } 3305 3306 case ISD::INTRINSIC_WO_CHAIN: { 3307 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 3308 switch (IntNo) { 3309 default: 3310 break; 3311 3312 case Intrinsic::arm_neon_vtbl2: 3313 return SelectVTBL(N, false, 2, ARM::VTBL2); 3314 case Intrinsic::arm_neon_vtbl3: 3315 return SelectVTBL(N, false, 3, ARM::VTBL3Pseudo); 3316 case Intrinsic::arm_neon_vtbl4: 3317 return SelectVTBL(N, false, 4, ARM::VTBL4Pseudo); 3318 3319 case Intrinsic::arm_neon_vtbx2: 3320 return SelectVTBL(N, true, 2, ARM::VTBX2); 3321 case Intrinsic::arm_neon_vtbx3: 3322 return SelectVTBL(N, true, 3, ARM::VTBX3Pseudo); 3323 case Intrinsic::arm_neon_vtbx4: 3324 return SelectVTBL(N, true, 4, ARM::VTBX4Pseudo); 3325 } 3326 break; 3327 } 3328 3329 case ARMISD::VTBL1: { 3330 SDLoc dl(N); 3331 EVT VT = N->getValueType(0); 3332 SmallVector<SDValue, 6> Ops; 3333 3334 Ops.push_back(N->getOperand(0)); 3335 Ops.push_back(N->getOperand(1)); 3336 Ops.push_back(getAL(CurDAG, dl)); // Predicate 3337 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // Predicate Register 3338 return CurDAG->getMachineNode(ARM::VTBL1, dl, VT, Ops); 3339 } 3340 case ARMISD::VTBL2: { 3341 SDLoc dl(N); 3342 EVT VT = N->getValueType(0); 3343 3344 // Form a REG_SEQUENCE to force register allocation. 3345 SDValue V0 = N->getOperand(0); 3346 SDValue V1 = N->getOperand(1); 3347 SDValue RegSeq = SDValue(createDRegPairNode(MVT::v16i8, V0, V1), 0); 3348 3349 SmallVector<SDValue, 6> Ops; 3350 Ops.push_back(RegSeq); 3351 Ops.push_back(N->getOperand(2)); 3352 Ops.push_back(getAL(CurDAG, dl)); // Predicate 3353 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // Predicate Register 3354 return CurDAG->getMachineNode(ARM::VTBL2, dl, VT, Ops); 3355 } 3356 3357 case ISD::CONCAT_VECTORS: 3358 return SelectConcatVector(N); 3359 } 3360 3361 return SelectCode(N); 3362 } 3363 3364 // Inspect a register string of the form 3365 // cp<coprocessor>:<opc1>:c<CRn>:c<CRm>:<opc2> (32bit) or 3366 // cp<coprocessor>:<opc1>:c<CRm> (64bit) inspect the fields of the string 3367 // and obtain the integer operands from them, adding these operands to the 3368 // provided vector. 3369 static void getIntOperandsFromRegisterString(StringRef RegString, 3370 SelectionDAG *CurDAG, SDLoc DL, 3371 std::vector<SDValue>& Ops) { 3372 SmallVector<StringRef, 5> Fields; 3373 RegString.split(Fields, ':'); 3374 3375 if (Fields.size() > 1) { 3376 bool AllIntFields = true; 3377 3378 for (StringRef Field : Fields) { 3379 // Need to trim out leading 'cp' characters and get the integer field. 3380 unsigned IntField; 3381 AllIntFields &= !Field.trim("CPcp").getAsInteger(10, IntField); 3382 Ops.push_back(CurDAG->getTargetConstant(IntField, DL, MVT::i32)); 3383 } 3384 3385 assert(AllIntFields && 3386 "Unexpected non-integer value in special register string."); 3387 } 3388 } 3389 3390 // Maps a Banked Register string to its mask value. The mask value returned is 3391 // for use in the MRSbanked / MSRbanked instruction nodes as the Banked Register 3392 // mask operand, which expresses which register is to be used, e.g. r8, and in 3393 // which mode it is to be used, e.g. usr. Returns -1 to signify that the string 3394 // was invalid. 3395 static inline int getBankedRegisterMask(StringRef RegString) { 3396 return StringSwitch<int>(RegString.lower()) 3397 .Case("r8_usr", 0x00) 3398 .Case("r9_usr", 0x01) 3399 .Case("r10_usr", 0x02) 3400 .Case("r11_usr", 0x03) 3401 .Case("r12_usr", 0x04) 3402 .Case("sp_usr", 0x05) 3403 .Case("lr_usr", 0x06) 3404 .Case("r8_fiq", 0x08) 3405 .Case("r9_fiq", 0x09) 3406 .Case("r10_fiq", 0x0a) 3407 .Case("r11_fiq", 0x0b) 3408 .Case("r12_fiq", 0x0c) 3409 .Case("sp_fiq", 0x0d) 3410 .Case("lr_fiq", 0x0e) 3411 .Case("lr_irq", 0x10) 3412 .Case("sp_irq", 0x11) 3413 .Case("lr_svc", 0x12) 3414 .Case("sp_svc", 0x13) 3415 .Case("lr_abt", 0x14) 3416 .Case("sp_abt", 0x15) 3417 .Case("lr_und", 0x16) 3418 .Case("sp_und", 0x17) 3419 .Case("lr_mon", 0x1c) 3420 .Case("sp_mon", 0x1d) 3421 .Case("elr_hyp", 0x1e) 3422 .Case("sp_hyp", 0x1f) 3423 .Case("spsr_fiq", 0x2e) 3424 .Case("spsr_irq", 0x30) 3425 .Case("spsr_svc", 0x32) 3426 .Case("spsr_abt", 0x34) 3427 .Case("spsr_und", 0x36) 3428 .Case("spsr_mon", 0x3c) 3429 .Case("spsr_hyp", 0x3e) 3430 .Default(-1); 3431 } 3432 3433 // Maps a MClass special register string to its value for use in the 3434 // t2MRS_M / t2MSR_M instruction nodes as the SYSm value operand. 3435 // Returns -1 to signify that the string was invalid. 3436 static inline int getMClassRegisterSYSmValueMask(StringRef RegString) { 3437 return StringSwitch<int>(RegString.lower()) 3438 .Case("apsr", 0x0) 3439 .Case("iapsr", 0x1) 3440 .Case("eapsr", 0x2) 3441 .Case("xpsr", 0x3) 3442 .Case("ipsr", 0x5) 3443 .Case("epsr", 0x6) 3444 .Case("iepsr", 0x7) 3445 .Case("msp", 0x8) 3446 .Case("psp", 0x9) 3447 .Case("primask", 0x10) 3448 .Case("basepri", 0x11) 3449 .Case("basepri_max", 0x12) 3450 .Case("faultmask", 0x13) 3451 .Case("control", 0x14) 3452 .Case("msplim", 0x0a) 3453 .Case("psplim", 0x0b) 3454 .Case("sp", 0x18) 3455 .Default(-1); 3456 } 3457 3458 // The flags here are common to those allowed for apsr in the A class cores and 3459 // those allowed for the special registers in the M class cores. Returns a 3460 // value representing which flags were present, -1 if invalid. 3461 static inline int getMClassFlagsMask(StringRef Flags, bool hasDSP) { 3462 if (Flags.empty()) 3463 return 0x2 | (int)hasDSP; 3464 3465 return StringSwitch<int>(Flags) 3466 .Case("g", 0x1) 3467 .Case("nzcvq", 0x2) 3468 .Case("nzcvqg", 0x3) 3469 .Default(-1); 3470 } 3471 3472 static int getMClassRegisterMask(StringRef Reg, StringRef Flags, bool IsRead, 3473 const ARMSubtarget *Subtarget) { 3474 // Ensure that the register (without flags) was a valid M Class special 3475 // register. 3476 int SYSmvalue = getMClassRegisterSYSmValueMask(Reg); 3477 if (SYSmvalue == -1) 3478 return -1; 3479 3480 // basepri, basepri_max and faultmask are only valid for V7m. 3481 if (!Subtarget->hasV7Ops() && SYSmvalue >= 0x11 && SYSmvalue <= 0x13) 3482 return -1; 3483 3484 if (Subtarget->has8MSecExt() && Flags.lower() == "ns") { 3485 Flags = ""; 3486 SYSmvalue |= 0x80; 3487 } 3488 3489 if (!Subtarget->has8MSecExt() && 3490 (SYSmvalue == 0xa || SYSmvalue == 0xb || SYSmvalue > 0x14)) 3491 return -1; 3492 3493 if (!Subtarget->hasV8MMainlineOps() && 3494 (SYSmvalue == 0x8a || SYSmvalue == 0x8b || SYSmvalue == 0x91 || 3495 SYSmvalue == 0x93)) 3496 return -1; 3497 3498 // If it was a read then we won't be expecting flags and so at this point 3499 // we can return the mask. 3500 if (IsRead) { 3501 if (Flags.empty()) 3502 return SYSmvalue; 3503 else 3504 return -1; 3505 } 3506 3507 // We know we are now handling a write so need to get the mask for the flags. 3508 int Mask = getMClassFlagsMask(Flags, Subtarget->hasDSP()); 3509 3510 // Only apsr, iapsr, eapsr, xpsr can have flags. The other register values 3511 // shouldn't have flags present. 3512 if ((SYSmvalue < 0x4 && Mask == -1) || (SYSmvalue > 0x4 && !Flags.empty())) 3513 return -1; 3514 3515 // The _g and _nzcvqg versions are only valid if the DSP extension is 3516 // available. 3517 if (!Subtarget->hasDSP() && (Mask & 0x1)) 3518 return -1; 3519 3520 // The register was valid so need to put the mask in the correct place 3521 // (the flags need to be in bits 11-10) and combine with the SYSmvalue to 3522 // construct the operand for the instruction node. 3523 if (SYSmvalue < 0x4) 3524 return SYSmvalue | Mask << 10; 3525 3526 return SYSmvalue; 3527 } 3528 3529 static int getARClassRegisterMask(StringRef Reg, StringRef Flags) { 3530 // The mask operand contains the special register (R Bit) in bit 4, whether 3531 // the register is spsr (R bit is 1) or one of cpsr/apsr (R bit is 0), and 3532 // bits 3-0 contains the fields to be accessed in the special register, set by 3533 // the flags provided with the register. 3534 int Mask = 0; 3535 if (Reg == "apsr") { 3536 // The flags permitted for apsr are the same flags that are allowed in 3537 // M class registers. We get the flag value and then shift the flags into 3538 // the correct place to combine with the mask. 3539 Mask = getMClassFlagsMask(Flags, true); 3540 if (Mask == -1) 3541 return -1; 3542 return Mask << 2; 3543 } 3544 3545 if (Reg != "cpsr" && Reg != "spsr") { 3546 return -1; 3547 } 3548 3549 // This is the same as if the flags were "fc" 3550 if (Flags.empty() || Flags == "all") 3551 return Mask | 0x9; 3552 3553 // Inspect the supplied flags string and set the bits in the mask for 3554 // the relevant and valid flags allowed for cpsr and spsr. 3555 for (char Flag : Flags) { 3556 int FlagVal; 3557 switch (Flag) { 3558 case 'c': 3559 FlagVal = 0x1; 3560 break; 3561 case 'x': 3562 FlagVal = 0x2; 3563 break; 3564 case 's': 3565 FlagVal = 0x4; 3566 break; 3567 case 'f': 3568 FlagVal = 0x8; 3569 break; 3570 default: 3571 FlagVal = 0; 3572 } 3573 3574 // This avoids allowing strings where the same flag bit appears twice. 3575 if (!FlagVal || (Mask & FlagVal)) 3576 return -1; 3577 Mask |= FlagVal; 3578 } 3579 3580 // If the register is spsr then we need to set the R bit. 3581 if (Reg == "spsr") 3582 Mask |= 0x10; 3583 3584 return Mask; 3585 } 3586 3587 // Lower the read_register intrinsic to ARM specific DAG nodes 3588 // using the supplied metadata string to select the instruction node to use 3589 // and the registers/masks to construct as operands for the node. 3590 SDNode *ARMDAGToDAGISel::SelectReadRegister(SDNode *N){ 3591 const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1)); 3592 const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0)); 3593 bool IsThumb2 = Subtarget->isThumb2(); 3594 SDLoc DL(N); 3595 3596 std::vector<SDValue> Ops; 3597 getIntOperandsFromRegisterString(RegString->getString(), CurDAG, DL, Ops); 3598 3599 if (!Ops.empty()) { 3600 // If the special register string was constructed of fields (as defined 3601 // in the ACLE) then need to lower to MRC node (32 bit) or 3602 // MRRC node(64 bit), we can make the distinction based on the number of 3603 // operands we have. 3604 unsigned Opcode; 3605 SmallVector<EVT, 3> ResTypes; 3606 if (Ops.size() == 5){ 3607 Opcode = IsThumb2 ? ARM::t2MRC : ARM::MRC; 3608 ResTypes.append({ MVT::i32, MVT::Other }); 3609 } else { 3610 assert(Ops.size() == 3 && 3611 "Invalid number of fields in special register string."); 3612 Opcode = IsThumb2 ? ARM::t2MRRC : ARM::MRRC; 3613 ResTypes.append({ MVT::i32, MVT::i32, MVT::Other }); 3614 } 3615 3616 Ops.push_back(getAL(CurDAG, DL)); 3617 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 3618 Ops.push_back(N->getOperand(0)); 3619 return CurDAG->getMachineNode(Opcode, DL, ResTypes, Ops); 3620 } 3621 3622 std::string SpecialReg = RegString->getString().lower(); 3623 3624 int BankedReg = getBankedRegisterMask(SpecialReg); 3625 if (BankedReg != -1) { 3626 Ops = { CurDAG->getTargetConstant(BankedReg, DL, MVT::i32), 3627 getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 3628 N->getOperand(0) }; 3629 return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSbanked : ARM::MRSbanked, 3630 DL, MVT::i32, MVT::Other, Ops); 3631 } 3632 3633 // The VFP registers are read by creating SelectionDAG nodes with opcodes 3634 // corresponding to the register that is being read from. So we switch on the 3635 // string to find which opcode we need to use. 3636 unsigned Opcode = StringSwitch<unsigned>(SpecialReg) 3637 .Case("fpscr", ARM::VMRS) 3638 .Case("fpexc", ARM::VMRS_FPEXC) 3639 .Case("fpsid", ARM::VMRS_FPSID) 3640 .Case("mvfr0", ARM::VMRS_MVFR0) 3641 .Case("mvfr1", ARM::VMRS_MVFR1) 3642 .Case("mvfr2", ARM::VMRS_MVFR2) 3643 .Case("fpinst", ARM::VMRS_FPINST) 3644 .Case("fpinst2", ARM::VMRS_FPINST2) 3645 .Default(0); 3646 3647 // If an opcode was found then we can lower the read to a VFP instruction. 3648 if (Opcode) { 3649 if (!Subtarget->hasVFP2()) 3650 return nullptr; 3651 if (Opcode == ARM::VMRS_MVFR2 && !Subtarget->hasFPARMv8()) 3652 return nullptr; 3653 3654 Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 3655 N->getOperand(0) }; 3656 return CurDAG->getMachineNode(Opcode, DL, MVT::i32, MVT::Other, Ops); 3657 } 3658 3659 // If the target is M Class then need to validate that the register string 3660 // is an acceptable value, so check that a mask can be constructed from the 3661 // string. 3662 if (Subtarget->isMClass()) { 3663 StringRef Flags = "", Reg = SpecialReg; 3664 if (Reg.endswith("_ns")) { 3665 Flags = "ns"; 3666 Reg = Reg.drop_back(3); 3667 } 3668 3669 int SYSmValue = getMClassRegisterMask(Reg, Flags, true, Subtarget); 3670 if (SYSmValue == -1) 3671 return nullptr; 3672 3673 SDValue Ops[] = { CurDAG->getTargetConstant(SYSmValue, DL, MVT::i32), 3674 getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 3675 N->getOperand(0) }; 3676 return CurDAG->getMachineNode(ARM::t2MRS_M, DL, MVT::i32, MVT::Other, Ops); 3677 } 3678 3679 // Here we know the target is not M Class so we need to check if it is one 3680 // of the remaining possible values which are apsr, cpsr or spsr. 3681 if (SpecialReg == "apsr" || SpecialReg == "cpsr") { 3682 Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 3683 N->getOperand(0) }; 3684 return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRS_AR : ARM::MRS, DL, 3685 MVT::i32, MVT::Other, Ops); 3686 } 3687 3688 if (SpecialReg == "spsr") { 3689 Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 3690 N->getOperand(0) }; 3691 return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSsys_AR : ARM::MRSsys, 3692 DL, MVT::i32, MVT::Other, Ops); 3693 } 3694 3695 return nullptr; 3696 } 3697 3698 // Lower the write_register intrinsic to ARM specific DAG nodes 3699 // using the supplied metadata string to select the instruction node to use 3700 // and the registers/masks to use in the nodes 3701 SDNode *ARMDAGToDAGISel::SelectWriteRegister(SDNode *N){ 3702 const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1)); 3703 const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0)); 3704 bool IsThumb2 = Subtarget->isThumb2(); 3705 SDLoc DL(N); 3706 3707 std::vector<SDValue> Ops; 3708 getIntOperandsFromRegisterString(RegString->getString(), CurDAG, DL, Ops); 3709 3710 if (!Ops.empty()) { 3711 // If the special register string was constructed of fields (as defined 3712 // in the ACLE) then need to lower to MCR node (32 bit) or 3713 // MCRR node(64 bit), we can make the distinction based on the number of 3714 // operands we have. 3715 unsigned Opcode; 3716 if (Ops.size() == 5) { 3717 Opcode = IsThumb2 ? ARM::t2MCR : ARM::MCR; 3718 Ops.insert(Ops.begin()+2, N->getOperand(2)); 3719 } else { 3720 assert(Ops.size() == 3 && 3721 "Invalid number of fields in special register string."); 3722 Opcode = IsThumb2 ? ARM::t2MCRR : ARM::MCRR; 3723 SDValue WriteValue[] = { N->getOperand(2), N->getOperand(3) }; 3724 Ops.insert(Ops.begin()+2, WriteValue, WriteValue+2); 3725 } 3726 3727 Ops.push_back(getAL(CurDAG, DL)); 3728 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); 3729 Ops.push_back(N->getOperand(0)); 3730 3731 return CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops); 3732 } 3733 3734 std::string SpecialReg = RegString->getString().lower(); 3735 int BankedReg = getBankedRegisterMask(SpecialReg); 3736 if (BankedReg != -1) { 3737 Ops = { CurDAG->getTargetConstant(BankedReg, DL, MVT::i32), N->getOperand(2), 3738 getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 3739 N->getOperand(0) }; 3740 return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSRbanked : ARM::MSRbanked, 3741 DL, MVT::Other, Ops); 3742 } 3743 3744 // The VFP registers are written to by creating SelectionDAG nodes with 3745 // opcodes corresponding to the register that is being written. So we switch 3746 // on the string to find which opcode we need to use. 3747 unsigned Opcode = StringSwitch<unsigned>(SpecialReg) 3748 .Case("fpscr", ARM::VMSR) 3749 .Case("fpexc", ARM::VMSR_FPEXC) 3750 .Case("fpsid", ARM::VMSR_FPSID) 3751 .Case("fpinst", ARM::VMSR_FPINST) 3752 .Case("fpinst2", ARM::VMSR_FPINST2) 3753 .Default(0); 3754 3755 if (Opcode) { 3756 if (!Subtarget->hasVFP2()) 3757 return nullptr; 3758 Ops = { N->getOperand(2), getAL(CurDAG, DL), 3759 CurDAG->getRegister(0, MVT::i32), N->getOperand(0) }; 3760 return CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops); 3761 } 3762 3763 std::pair<StringRef, StringRef> Fields; 3764 Fields = StringRef(SpecialReg).rsplit('_'); 3765 std::string Reg = Fields.first.str(); 3766 StringRef Flags = Fields.second; 3767 3768 // If the target was M Class then need to validate the special register value 3769 // and retrieve the mask for use in the instruction node. 3770 if (Subtarget->isMClass()) { 3771 // basepri_max gets split so need to correct Reg and Flags. 3772 if (SpecialReg == "basepri_max") { 3773 Reg = SpecialReg; 3774 Flags = ""; 3775 } 3776 int SYSmValue = getMClassRegisterMask(Reg, Flags, false, Subtarget); 3777 if (SYSmValue == -1) 3778 return nullptr; 3779 3780 SDValue Ops[] = { CurDAG->getTargetConstant(SYSmValue, DL, MVT::i32), 3781 N->getOperand(2), getAL(CurDAG, DL), 3782 CurDAG->getRegister(0, MVT::i32), N->getOperand(0) }; 3783 return CurDAG->getMachineNode(ARM::t2MSR_M, DL, MVT::Other, Ops); 3784 } 3785 3786 // We then check to see if a valid mask can be constructed for one of the 3787 // register string values permitted for the A and R class cores. These values 3788 // are apsr, spsr and cpsr; these are also valid on older cores. 3789 int Mask = getARClassRegisterMask(Reg, Flags); 3790 if (Mask != -1) { 3791 Ops = { CurDAG->getTargetConstant(Mask, DL, MVT::i32), N->getOperand(2), 3792 getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), 3793 N->getOperand(0) }; 3794 return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSR_AR : ARM::MSR, 3795 DL, MVT::Other, Ops); 3796 } 3797 3798 return nullptr; 3799 } 3800 3801 SDNode *ARMDAGToDAGISel::SelectInlineAsm(SDNode *N){ 3802 std::vector<SDValue> AsmNodeOperands; 3803 unsigned Flag, Kind; 3804 bool Changed = false; 3805 unsigned NumOps = N->getNumOperands(); 3806 3807 // Normally, i64 data is bounded to two arbitrary GRPs for "%r" constraint. 3808 // However, some instrstions (e.g. ldrexd/strexd in ARM mode) require 3809 // (even/even+1) GPRs and use %n and %Hn to refer to the individual regs 3810 // respectively. Since there is no constraint to explicitly specify a 3811 // reg pair, we use GPRPair reg class for "%r" for 64-bit data. For Thumb, 3812 // the 64-bit data may be referred by H, Q, R modifiers, so we still pack 3813 // them into a GPRPair. 3814 3815 SDLoc dl(N); 3816 SDValue Glue = N->getGluedNode() ? N->getOperand(NumOps-1) 3817 : SDValue(nullptr,0); 3818 3819 SmallVector<bool, 8> OpChanged; 3820 // Glue node will be appended late. 3821 for(unsigned i = 0, e = N->getGluedNode() ? NumOps - 1 : NumOps; i < e; ++i) { 3822 SDValue op = N->getOperand(i); 3823 AsmNodeOperands.push_back(op); 3824 3825 if (i < InlineAsm::Op_FirstOperand) 3826 continue; 3827 3828 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(i))) { 3829 Flag = C->getZExtValue(); 3830 Kind = InlineAsm::getKind(Flag); 3831 } 3832 else 3833 continue; 3834 3835 // Immediate operands to inline asm in the SelectionDAG are modeled with 3836 // two operands. The first is a constant of value InlineAsm::Kind_Imm, and 3837 // the second is a constant with the value of the immediate. If we get here 3838 // and we have a Kind_Imm, skip the next operand, and continue. 3839 if (Kind == InlineAsm::Kind_Imm) { 3840 SDValue op = N->getOperand(++i); 3841 AsmNodeOperands.push_back(op); 3842 continue; 3843 } 3844 3845 unsigned NumRegs = InlineAsm::getNumOperandRegisters(Flag); 3846 if (NumRegs) 3847 OpChanged.push_back(false); 3848 3849 unsigned DefIdx = 0; 3850 bool IsTiedToChangedOp = false; 3851 // If it's a use that is tied with a previous def, it has no 3852 // reg class constraint. 3853 if (Changed && InlineAsm::isUseOperandTiedToDef(Flag, DefIdx)) 3854 IsTiedToChangedOp = OpChanged[DefIdx]; 3855 3856 if (Kind != InlineAsm::Kind_RegUse && Kind != InlineAsm::Kind_RegDef 3857 && Kind != InlineAsm::Kind_RegDefEarlyClobber) 3858 continue; 3859 3860 unsigned RC; 3861 bool HasRC = InlineAsm::hasRegClassConstraint(Flag, RC); 3862 if ((!IsTiedToChangedOp && (!HasRC || RC != ARM::GPRRegClassID)) 3863 || NumRegs != 2) 3864 continue; 3865 3866 assert((i+2 < NumOps) && "Invalid number of operands in inline asm"); 3867 SDValue V0 = N->getOperand(i+1); 3868 SDValue V1 = N->getOperand(i+2); 3869 unsigned Reg0 = cast<RegisterSDNode>(V0)->getReg(); 3870 unsigned Reg1 = cast<RegisterSDNode>(V1)->getReg(); 3871 SDValue PairedReg; 3872 MachineRegisterInfo &MRI = MF->getRegInfo(); 3873 3874 if (Kind == InlineAsm::Kind_RegDef || 3875 Kind == InlineAsm::Kind_RegDefEarlyClobber) { 3876 // Replace the two GPRs with 1 GPRPair and copy values from GPRPair to 3877 // the original GPRs. 3878 3879 unsigned GPVR = MRI.createVirtualRegister(&ARM::GPRPairRegClass); 3880 PairedReg = CurDAG->getRegister(GPVR, MVT::Untyped); 3881 SDValue Chain = SDValue(N,0); 3882 3883 SDNode *GU = N->getGluedUser(); 3884 SDValue RegCopy = CurDAG->getCopyFromReg(Chain, dl, GPVR, MVT::Untyped, 3885 Chain.getValue(1)); 3886 3887 // Extract values from a GPRPair reg and copy to the original GPR reg. 3888 SDValue Sub0 = CurDAG->getTargetExtractSubreg(ARM::gsub_0, dl, MVT::i32, 3889 RegCopy); 3890 SDValue Sub1 = CurDAG->getTargetExtractSubreg(ARM::gsub_1, dl, MVT::i32, 3891 RegCopy); 3892 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0, 3893 RegCopy.getValue(1)); 3894 SDValue T1 = CurDAG->getCopyToReg(Sub1, dl, Reg1, Sub1, T0.getValue(1)); 3895 3896 // Update the original glue user. 3897 std::vector<SDValue> Ops(GU->op_begin(), GU->op_end()-1); 3898 Ops.push_back(T1.getValue(1)); 3899 CurDAG->UpdateNodeOperands(GU, Ops); 3900 } 3901 else { 3902 // For Kind == InlineAsm::Kind_RegUse, we first copy two GPRs into a 3903 // GPRPair and then pass the GPRPair to the inline asm. 3904 SDValue Chain = AsmNodeOperands[InlineAsm::Op_InputChain]; 3905 3906 // As REG_SEQ doesn't take RegisterSDNode, we copy them first. 3907 SDValue T0 = CurDAG->getCopyFromReg(Chain, dl, Reg0, MVT::i32, 3908 Chain.getValue(1)); 3909 SDValue T1 = CurDAG->getCopyFromReg(Chain, dl, Reg1, MVT::i32, 3910 T0.getValue(1)); 3911 SDValue Pair = SDValue(createGPRPairNode(MVT::Untyped, T0, T1), 0); 3912 3913 // Copy REG_SEQ into a GPRPair-typed VR and replace the original two 3914 // i32 VRs of inline asm with it. 3915 unsigned GPVR = MRI.createVirtualRegister(&ARM::GPRPairRegClass); 3916 PairedReg = CurDAG->getRegister(GPVR, MVT::Untyped); 3917 Chain = CurDAG->getCopyToReg(T1, dl, GPVR, Pair, T1.getValue(1)); 3918 3919 AsmNodeOperands[InlineAsm::Op_InputChain] = Chain; 3920 Glue = Chain.getValue(1); 3921 } 3922 3923 Changed = true; 3924 3925 if(PairedReg.getNode()) { 3926 OpChanged[OpChanged.size() -1 ] = true; 3927 Flag = InlineAsm::getFlagWord(Kind, 1 /* RegNum*/); 3928 if (IsTiedToChangedOp) 3929 Flag = InlineAsm::getFlagWordForMatchingOp(Flag, DefIdx); 3930 else 3931 Flag = InlineAsm::getFlagWordForRegClass(Flag, ARM::GPRPairRegClassID); 3932 // Replace the current flag. 3933 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant( 3934 Flag, dl, MVT::i32); 3935 // Add the new register node and skip the original two GPRs. 3936 AsmNodeOperands.push_back(PairedReg); 3937 // Skip the next two GPRs. 3938 i += 2; 3939 } 3940 } 3941 3942 if (Glue.getNode()) 3943 AsmNodeOperands.push_back(Glue); 3944 if (!Changed) 3945 return nullptr; 3946 3947 SDValue New = CurDAG->getNode(ISD::INLINEASM, SDLoc(N), 3948 CurDAG->getVTList(MVT::Other, MVT::Glue), AsmNodeOperands); 3949 New->setNodeId(-1); 3950 return New.getNode(); 3951 } 3952 3953 3954 bool ARMDAGToDAGISel:: 3955 SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 3956 std::vector<SDValue> &OutOps) { 3957 switch(ConstraintID) { 3958 default: 3959 llvm_unreachable("Unexpected asm memory constraint"); 3960 case InlineAsm::Constraint_i: 3961 // FIXME: It seems strange that 'i' is needed here since it's supposed to 3962 // be an immediate and not a memory constraint. 3963 // Fallthrough. 3964 case InlineAsm::Constraint_m: 3965 case InlineAsm::Constraint_o: 3966 case InlineAsm::Constraint_Q: 3967 case InlineAsm::Constraint_Um: 3968 case InlineAsm::Constraint_Un: 3969 case InlineAsm::Constraint_Uq: 3970 case InlineAsm::Constraint_Us: 3971 case InlineAsm::Constraint_Ut: 3972 case InlineAsm::Constraint_Uv: 3973 case InlineAsm::Constraint_Uy: 3974 // Require the address to be in a register. That is safe for all ARM 3975 // variants and it is hard to do anything much smarter without knowing 3976 // how the operand is used. 3977 OutOps.push_back(Op); 3978 return false; 3979 } 3980 return true; 3981 } 3982 3983 /// createARMISelDag - This pass converts a legalized DAG into a 3984 /// ARM-specific DAG, ready for instruction scheduling. 3985 /// 3986 FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM, 3987 CodeGenOpt::Level OptLevel) { 3988 return new ARMDAGToDAGISel(TM, OptLevel); 3989 } 3990