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