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