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