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