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