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