ARMISelDAGToDAG.cpp revision 203954
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 "ARMAddressingModes.h" 16#include "ARMISelLowering.h" 17#include "ARMTargetMachine.h" 18#include "llvm/CallingConv.h" 19#include "llvm/Constants.h" 20#include "llvm/DerivedTypes.h" 21#include "llvm/Function.h" 22#include "llvm/Intrinsics.h" 23#include "llvm/LLVMContext.h" 24#include "llvm/CodeGen/MachineFrameInfo.h" 25#include "llvm/CodeGen/MachineFunction.h" 26#include "llvm/CodeGen/MachineInstrBuilder.h" 27#include "llvm/CodeGen/SelectionDAG.h" 28#include "llvm/CodeGen/SelectionDAGISel.h" 29#include "llvm/Target/TargetLowering.h" 30#include "llvm/Target/TargetOptions.h" 31#include "llvm/Support/Compiler.h" 32#include "llvm/Support/Debug.h" 33#include "llvm/Support/ErrorHandling.h" 34#include "llvm/Support/raw_ostream.h" 35 36using namespace llvm; 37 38//===--------------------------------------------------------------------===// 39/// ARMDAGToDAGISel - ARM specific code to select ARM machine 40/// instructions for SelectionDAG operations. 41/// 42namespace { 43class ARMDAGToDAGISel : public SelectionDAGISel { 44 ARMBaseTargetMachine &TM; 45 46 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 47 /// make the right decision when generating code for different targets. 48 const ARMSubtarget *Subtarget; 49 50public: 51 explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm, 52 CodeGenOpt::Level OptLevel) 53 : SelectionDAGISel(tm, OptLevel), TM(tm), 54 Subtarget(&TM.getSubtarget<ARMSubtarget>()) { 55 } 56 57 virtual const char *getPassName() const { 58 return "ARM Instruction Selection"; 59 } 60 61 virtual void InstructionSelect(); 62 63 /// getI32Imm - Return a target constant of type i32 with the specified 64 /// value. 65 inline SDValue getI32Imm(unsigned Imm) { 66 return CurDAG->getTargetConstant(Imm, MVT::i32); 67 } 68 69 SDNode *Select(SDNode *N); 70 71 bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A, 72 SDValue &B, SDValue &C); 73 bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base, 74 SDValue &Offset, SDValue &Opc); 75 bool SelectAddrMode2Offset(SDNode *Op, SDValue N, 76 SDValue &Offset, SDValue &Opc); 77 bool SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base, 78 SDValue &Offset, SDValue &Opc); 79 bool SelectAddrMode3Offset(SDNode *Op, SDValue N, 80 SDValue &Offset, SDValue &Opc); 81 bool SelectAddrMode4(SDNode *Op, SDValue N, SDValue &Addr, 82 SDValue &Mode); 83 bool SelectAddrMode5(SDNode *Op, SDValue N, SDValue &Base, 84 SDValue &Offset); 85 bool SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Update, 86 SDValue &Opc, SDValue &Align); 87 88 bool SelectAddrModePC(SDNode *Op, SDValue N, SDValue &Offset, 89 SDValue &Label); 90 91 bool SelectThumbAddrModeRR(SDNode *Op, SDValue N, SDValue &Base, 92 SDValue &Offset); 93 bool SelectThumbAddrModeRI5(SDNode *Op, SDValue N, unsigned Scale, 94 SDValue &Base, SDValue &OffImm, 95 SDValue &Offset); 96 bool SelectThumbAddrModeS1(SDNode *Op, SDValue N, SDValue &Base, 97 SDValue &OffImm, SDValue &Offset); 98 bool SelectThumbAddrModeS2(SDNode *Op, SDValue N, SDValue &Base, 99 SDValue &OffImm, SDValue &Offset); 100 bool SelectThumbAddrModeS4(SDNode *Op, SDValue N, SDValue &Base, 101 SDValue &OffImm, SDValue &Offset); 102 bool SelectThumbAddrModeSP(SDNode *Op, SDValue N, SDValue &Base, 103 SDValue &OffImm); 104 105 bool SelectT2ShifterOperandReg(SDNode *Op, SDValue N, 106 SDValue &BaseReg, SDValue &Opc); 107 bool SelectT2AddrModeImm12(SDNode *Op, SDValue N, SDValue &Base, 108 SDValue &OffImm); 109 bool SelectT2AddrModeImm8(SDNode *Op, SDValue N, SDValue &Base, 110 SDValue &OffImm); 111 bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 112 SDValue &OffImm); 113 bool SelectT2AddrModeImm8s4(SDNode *Op, SDValue N, SDValue &Base, 114 SDValue &OffImm); 115 bool SelectT2AddrModeSoReg(SDNode *Op, SDValue N, SDValue &Base, 116 SDValue &OffReg, SDValue &ShImm); 117 118 // Include the pieces autogenerated from the target description. 119#include "ARMGenDAGISel.inc" 120 121private: 122 /// SelectARMIndexedLoad - Indexed (pre/post inc/dec) load matching code for 123 /// ARM. 124 SDNode *SelectARMIndexedLoad(SDNode *N); 125 SDNode *SelectT2IndexedLoad(SDNode *N); 126 127 /// SelectDYN_ALLOC - Select dynamic alloc for Thumb. 128 SDNode *SelectDYN_ALLOC(SDNode *N); 129 130 /// SelectVLD - Select NEON load intrinsics. NumVecs should 131 /// be 2, 3 or 4. The opcode arrays specify the instructions used for 132 /// loads of D registers and even subregs and odd subregs of Q registers. 133 /// For NumVecs == 2, QOpcodes1 is not used. 134 SDNode *SelectVLD(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, 135 unsigned *QOpcodes0, unsigned *QOpcodes1); 136 137 /// SelectVST - Select NEON store intrinsics. NumVecs should 138 /// be 2, 3 or 4. The opcode arrays specify the instructions used for 139 /// stores of D registers and even subregs and odd subregs of Q registers. 140 /// For NumVecs == 2, QOpcodes1 is not used. 141 SDNode *SelectVST(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, 142 unsigned *QOpcodes0, unsigned *QOpcodes1); 143 144 /// SelectVLDSTLane - Select NEON load/store lane intrinsics. NumVecs should 145 /// be 2, 3 or 4. The opcode arrays specify the instructions used for 146 /// load/store of D registers and even subregs and odd subregs of Q registers. 147 SDNode *SelectVLDSTLane(SDNode *N, bool IsLoad, unsigned NumVecs, 148 unsigned *DOpcodes, unsigned *QOpcodes0, 149 unsigned *QOpcodes1); 150 151 /// SelectV6T2BitfieldExtractOp - Select SBFX/UBFX instructions for ARM. 152 SDNode *SelectV6T2BitfieldExtractOp(SDNode *N, unsigned Opc); 153 154 /// SelectCMOVOp - Select CMOV instructions for ARM. 155 SDNode *SelectCMOVOp(SDNode *N); 156 SDNode *SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 157 ARMCC::CondCodes CCVal, SDValue CCR, 158 SDValue InFlag); 159 SDNode *SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 160 ARMCC::CondCodes CCVal, SDValue CCR, 161 SDValue InFlag); 162 SDNode *SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 163 ARMCC::CondCodes CCVal, SDValue CCR, 164 SDValue InFlag); 165 SDNode *SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 166 ARMCC::CondCodes CCVal, SDValue CCR, 167 SDValue InFlag); 168 169 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 170 /// inline asm expressions. 171 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 172 char ConstraintCode, 173 std::vector<SDValue> &OutOps); 174 175 /// PairDRegs - Insert a pair of double registers into an implicit def to 176 /// form a quad register. 177 SDNode *PairDRegs(EVT VT, SDValue V0, SDValue V1); 178}; 179} 180 181/// isInt32Immediate - This method tests to see if the node is a 32-bit constant 182/// operand. If so Imm will receive the 32-bit value. 183static bool isInt32Immediate(SDNode *N, unsigned &Imm) { 184 if (N->getOpcode() == ISD::Constant && N->getValueType(0) == MVT::i32) { 185 Imm = cast<ConstantSDNode>(N)->getZExtValue(); 186 return true; 187 } 188 return false; 189} 190 191// isInt32Immediate - This method tests to see if a constant operand. 192// If so Imm will receive the 32 bit value. 193static bool isInt32Immediate(SDValue N, unsigned &Imm) { 194 return isInt32Immediate(N.getNode(), Imm); 195} 196 197// isOpcWithIntImmediate - This method tests to see if the node is a specific 198// opcode and that it has a immediate integer right operand. 199// If so Imm will receive the 32 bit value. 200static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) { 201 return N->getOpcode() == Opc && 202 isInt32Immediate(N->getOperand(1).getNode(), Imm); 203} 204 205 206void ARMDAGToDAGISel::InstructionSelect() { 207 SelectRoot(*CurDAG); 208 CurDAG->RemoveDeadNodes(); 209} 210 211bool ARMDAGToDAGISel::SelectShifterOperandReg(SDNode *Op, 212 SDValue N, 213 SDValue &BaseReg, 214 SDValue &ShReg, 215 SDValue &Opc) { 216 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 217 218 // Don't match base register only case. That is matched to a separate 219 // lower complexity pattern with explicit register operand. 220 if (ShOpcVal == ARM_AM::no_shift) return false; 221 222 BaseReg = N.getOperand(0); 223 unsigned ShImmVal = 0; 224 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 225 ShReg = CurDAG->getRegister(0, MVT::i32); 226 ShImmVal = RHS->getZExtValue() & 31; 227 } else { 228 ShReg = N.getOperand(1); 229 } 230 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 231 MVT::i32); 232 return true; 233} 234 235bool ARMDAGToDAGISel::SelectAddrMode2(SDNode *Op, SDValue N, 236 SDValue &Base, SDValue &Offset, 237 SDValue &Opc) { 238 if (N.getOpcode() == ISD::MUL) { 239 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 240 // X * [3,5,9] -> X + X * [2,4,8] etc. 241 int RHSC = (int)RHS->getZExtValue(); 242 if (RHSC & 1) { 243 RHSC = RHSC & ~1; 244 ARM_AM::AddrOpc AddSub = ARM_AM::add; 245 if (RHSC < 0) { 246 AddSub = ARM_AM::sub; 247 RHSC = - RHSC; 248 } 249 if (isPowerOf2_32(RHSC)) { 250 unsigned ShAmt = Log2_32(RHSC); 251 Base = Offset = N.getOperand(0); 252 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, 253 ARM_AM::lsl), 254 MVT::i32); 255 return true; 256 } 257 } 258 } 259 } 260 261 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 262 Base = N; 263 if (N.getOpcode() == ISD::FrameIndex) { 264 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 265 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 266 } else if (N.getOpcode() == ARMISD::Wrapper && 267 !(Subtarget->useMovt() && 268 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 269 Base = N.getOperand(0); 270 } 271 Offset = CurDAG->getRegister(0, MVT::i32); 272 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, 273 ARM_AM::no_shift), 274 MVT::i32); 275 return true; 276 } 277 278 // Match simple R +/- imm12 operands. 279 if (N.getOpcode() == ISD::ADD) 280 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 281 int RHSC = (int)RHS->getZExtValue(); 282 if ((RHSC >= 0 && RHSC < 0x1000) || 283 (RHSC < 0 && RHSC > -0x1000)) { // 12 bits. 284 Base = N.getOperand(0); 285 if (Base.getOpcode() == ISD::FrameIndex) { 286 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 287 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 288 } 289 Offset = CurDAG->getRegister(0, MVT::i32); 290 291 ARM_AM::AddrOpc AddSub = ARM_AM::add; 292 if (RHSC < 0) { 293 AddSub = ARM_AM::sub; 294 RHSC = - RHSC; 295 } 296 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC, 297 ARM_AM::no_shift), 298 MVT::i32); 299 return true; 300 } 301 } 302 303 // Otherwise this is R +/- [possibly shifted] R. 304 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub; 305 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1)); 306 unsigned ShAmt = 0; 307 308 Base = N.getOperand(0); 309 Offset = N.getOperand(1); 310 311 if (ShOpcVal != ARM_AM::no_shift) { 312 // Check to see if the RHS of the shift is a constant, if not, we can't fold 313 // it. 314 if (ConstantSDNode *Sh = 315 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) { 316 ShAmt = Sh->getZExtValue(); 317 Offset = N.getOperand(1).getOperand(0); 318 } else { 319 ShOpcVal = ARM_AM::no_shift; 320 } 321 } 322 323 // Try matching (R shl C) + (R). 324 if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) { 325 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0)); 326 if (ShOpcVal != ARM_AM::no_shift) { 327 // Check to see if the RHS of the shift is a constant, if not, we can't 328 // fold it. 329 if (ConstantSDNode *Sh = 330 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) { 331 ShAmt = Sh->getZExtValue(); 332 Offset = N.getOperand(0).getOperand(0); 333 Base = N.getOperand(1); 334 } else { 335 ShOpcVal = ARM_AM::no_shift; 336 } 337 } 338 } 339 340 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 341 MVT::i32); 342 return true; 343} 344 345bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N, 346 SDValue &Offset, SDValue &Opc) { 347 unsigned Opcode = Op->getOpcode(); 348 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 349 ? cast<LoadSDNode>(Op)->getAddressingMode() 350 : cast<StoreSDNode>(Op)->getAddressingMode(); 351 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 352 ? ARM_AM::add : ARM_AM::sub; 353 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 354 int Val = (int)C->getZExtValue(); 355 if (Val >= 0 && Val < 0x1000) { // 12 bits. 356 Offset = CurDAG->getRegister(0, MVT::i32); 357 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, 358 ARM_AM::no_shift), 359 MVT::i32); 360 return true; 361 } 362 } 363 364 Offset = N; 365 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 366 unsigned ShAmt = 0; 367 if (ShOpcVal != ARM_AM::no_shift) { 368 // Check to see if the RHS of the shift is a constant, if not, we can't fold 369 // it. 370 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 371 ShAmt = Sh->getZExtValue(); 372 Offset = N.getOperand(0); 373 } else { 374 ShOpcVal = ARM_AM::no_shift; 375 } 376 } 377 378 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 379 MVT::i32); 380 return true; 381} 382 383 384bool ARMDAGToDAGISel::SelectAddrMode3(SDNode *Op, SDValue N, 385 SDValue &Base, SDValue &Offset, 386 SDValue &Opc) { 387 if (N.getOpcode() == ISD::SUB) { 388 // X - C is canonicalize to X + -C, no need to handle it here. 389 Base = N.getOperand(0); 390 Offset = N.getOperand(1); 391 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32); 392 return true; 393 } 394 395 if (N.getOpcode() != ISD::ADD) { 396 Base = N; 397 if (N.getOpcode() == ISD::FrameIndex) { 398 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 399 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 400 } 401 Offset = CurDAG->getRegister(0, MVT::i32); 402 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32); 403 return true; 404 } 405 406 // If the RHS is +/- imm8, fold into addr mode. 407 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 408 int RHSC = (int)RHS->getZExtValue(); 409 if ((RHSC >= 0 && RHSC < 256) || 410 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 411 Base = N.getOperand(0); 412 if (Base.getOpcode() == ISD::FrameIndex) { 413 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 414 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 415 } 416 Offset = CurDAG->getRegister(0, MVT::i32); 417 418 ARM_AM::AddrOpc AddSub = ARM_AM::add; 419 if (RHSC < 0) { 420 AddSub = ARM_AM::sub; 421 RHSC = - RHSC; 422 } 423 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32); 424 return true; 425 } 426 } 427 428 Base = N.getOperand(0); 429 Offset = N.getOperand(1); 430 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32); 431 return true; 432} 433 434bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N, 435 SDValue &Offset, SDValue &Opc) { 436 unsigned Opcode = Op->getOpcode(); 437 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 438 ? cast<LoadSDNode>(Op)->getAddressingMode() 439 : cast<StoreSDNode>(Op)->getAddressingMode(); 440 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 441 ? ARM_AM::add : ARM_AM::sub; 442 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 443 int Val = (int)C->getZExtValue(); 444 if (Val >= 0 && Val < 256) { 445 Offset = CurDAG->getRegister(0, MVT::i32); 446 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32); 447 return true; 448 } 449 } 450 451 Offset = N; 452 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32); 453 return true; 454} 455 456bool ARMDAGToDAGISel::SelectAddrMode4(SDNode *Op, SDValue N, 457 SDValue &Addr, SDValue &Mode) { 458 Addr = N; 459 Mode = CurDAG->getTargetConstant(0, MVT::i32); 460 return true; 461} 462 463bool ARMDAGToDAGISel::SelectAddrMode5(SDNode *Op, SDValue N, 464 SDValue &Base, SDValue &Offset) { 465 if (N.getOpcode() != ISD::ADD) { 466 Base = N; 467 if (N.getOpcode() == ISD::FrameIndex) { 468 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 469 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 470 } else if (N.getOpcode() == ARMISD::Wrapper && 471 !(Subtarget->useMovt() && 472 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 473 Base = N.getOperand(0); 474 } 475 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 476 MVT::i32); 477 return true; 478 } 479 480 // If the RHS is +/- imm8, fold into addr mode. 481 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 482 int RHSC = (int)RHS->getZExtValue(); 483 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied by 4. 484 RHSC >>= 2; 485 if ((RHSC >= 0 && RHSC < 256) || 486 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 487 Base = N.getOperand(0); 488 if (Base.getOpcode() == ISD::FrameIndex) { 489 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 490 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 491 } 492 493 ARM_AM::AddrOpc AddSub = ARM_AM::add; 494 if (RHSC < 0) { 495 AddSub = ARM_AM::sub; 496 RHSC = - RHSC; 497 } 498 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC), 499 MVT::i32); 500 return true; 501 } 502 } 503 } 504 505 Base = N; 506 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 507 MVT::i32); 508 return true; 509} 510 511bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Op, SDValue N, 512 SDValue &Addr, SDValue &Update, 513 SDValue &Opc, SDValue &Align) { 514 Addr = N; 515 // Default to no writeback. 516 Update = CurDAG->getRegister(0, MVT::i32); 517 Opc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(false), MVT::i32); 518 // Default to no alignment. 519 Align = CurDAG->getTargetConstant(0, MVT::i32); 520 return true; 521} 522 523bool ARMDAGToDAGISel::SelectAddrModePC(SDNode *Op, SDValue N, 524 SDValue &Offset, SDValue &Label) { 525 if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { 526 Offset = N.getOperand(0); 527 SDValue N1 = N.getOperand(1); 528 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(), 529 MVT::i32); 530 return true; 531 } 532 return false; 533} 534 535bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDNode *Op, SDValue N, 536 SDValue &Base, SDValue &Offset){ 537 // FIXME dl should come from the parent load or store, not the address 538 DebugLoc dl = Op->getDebugLoc(); 539 if (N.getOpcode() != ISD::ADD) { 540 ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N); 541 if (!NC || NC->getZExtValue() != 0) 542 return false; 543 544 Base = Offset = N; 545 return true; 546 } 547 548 Base = N.getOperand(0); 549 Offset = N.getOperand(1); 550 return true; 551} 552 553bool 554ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDNode *Op, SDValue N, 555 unsigned Scale, SDValue &Base, 556 SDValue &OffImm, SDValue &Offset) { 557 if (Scale == 4) { 558 SDValue TmpBase, TmpOffImm; 559 if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm)) 560 return false; // We want to select tLDRspi / tSTRspi instead. 561 if (N.getOpcode() == ARMISD::Wrapper && 562 N.getOperand(0).getOpcode() == ISD::TargetConstantPool) 563 return false; // We want to select tLDRpci instead. 564 } 565 566 if (N.getOpcode() != ISD::ADD) { 567 if (N.getOpcode() == ARMISD::Wrapper && 568 !(Subtarget->useMovt() && 569 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 570 Base = N.getOperand(0); 571 } else 572 Base = N; 573 574 Offset = CurDAG->getRegister(0, MVT::i32); 575 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 576 return true; 577 } 578 579 // Thumb does not have [sp, r] address mode. 580 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 581 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1)); 582 if ((LHSR && LHSR->getReg() == ARM::SP) || 583 (RHSR && RHSR->getReg() == ARM::SP)) { 584 Base = N; 585 Offset = CurDAG->getRegister(0, MVT::i32); 586 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 587 return true; 588 } 589 590 // If the RHS is + imm5 * scale, fold into addr mode. 591 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 592 int RHSC = (int)RHS->getZExtValue(); 593 if ((RHSC & (Scale-1)) == 0) { // The constant is implicitly multiplied. 594 RHSC /= Scale; 595 if (RHSC >= 0 && RHSC < 32) { 596 Base = N.getOperand(0); 597 Offset = CurDAG->getRegister(0, MVT::i32); 598 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 599 return true; 600 } 601 } 602 } 603 604 Base = N.getOperand(0); 605 Offset = N.getOperand(1); 606 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 607 return true; 608} 609 610bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDNode *Op, SDValue N, 611 SDValue &Base, SDValue &OffImm, 612 SDValue &Offset) { 613 return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset); 614} 615 616bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDNode *Op, SDValue N, 617 SDValue &Base, SDValue &OffImm, 618 SDValue &Offset) { 619 return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset); 620} 621 622bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDNode *Op, SDValue N, 623 SDValue &Base, SDValue &OffImm, 624 SDValue &Offset) { 625 return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset); 626} 627 628bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDNode *Op, SDValue N, 629 SDValue &Base, SDValue &OffImm) { 630 if (N.getOpcode() == ISD::FrameIndex) { 631 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 632 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 633 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 634 return true; 635 } 636 637 if (N.getOpcode() != ISD::ADD) 638 return false; 639 640 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 641 if (N.getOperand(0).getOpcode() == ISD::FrameIndex || 642 (LHSR && LHSR->getReg() == ARM::SP)) { 643 // If the RHS is + imm8 * scale, fold into addr mode. 644 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 645 int RHSC = (int)RHS->getZExtValue(); 646 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied. 647 RHSC >>= 2; 648 if (RHSC >= 0 && RHSC < 256) { 649 Base = N.getOperand(0); 650 if (Base.getOpcode() == ISD::FrameIndex) { 651 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 652 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 653 } 654 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 655 return true; 656 } 657 } 658 } 659 } 660 661 return false; 662} 663 664bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDNode *Op, SDValue N, 665 SDValue &BaseReg, 666 SDValue &Opc) { 667 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 668 669 // Don't match base register only case. That is matched to a separate 670 // lower complexity pattern with explicit register operand. 671 if (ShOpcVal == ARM_AM::no_shift) return false; 672 673 BaseReg = N.getOperand(0); 674 unsigned ShImmVal = 0; 675 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 676 ShImmVal = RHS->getZExtValue() & 31; 677 Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal)); 678 return true; 679 } 680 681 return false; 682} 683 684bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDNode *Op, SDValue N, 685 SDValue &Base, SDValue &OffImm) { 686 // Match simple R + imm12 operands. 687 688 // Base only. 689 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 690 if (N.getOpcode() == ISD::FrameIndex) { 691 // Match frame index... 692 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 693 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 694 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 695 return true; 696 } else if (N.getOpcode() == ARMISD::Wrapper && 697 !(Subtarget->useMovt() && 698 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 699 Base = N.getOperand(0); 700 if (Base.getOpcode() == ISD::TargetConstantPool) 701 return false; // We want to select t2LDRpci instead. 702 } else 703 Base = N; 704 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 705 return true; 706 } 707 708 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 709 if (SelectT2AddrModeImm8(Op, N, Base, OffImm)) 710 // Let t2LDRi8 handle (R - imm8). 711 return false; 712 713 int RHSC = (int)RHS->getZExtValue(); 714 if (N.getOpcode() == ISD::SUB) 715 RHSC = -RHSC; 716 717 if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits (unsigned) 718 Base = N.getOperand(0); 719 if (Base.getOpcode() == ISD::FrameIndex) { 720 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 721 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 722 } 723 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 724 return true; 725 } 726 } 727 728 // Base only. 729 Base = N; 730 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 731 return true; 732} 733 734bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDNode *Op, SDValue N, 735 SDValue &Base, SDValue &OffImm) { 736 // Match simple R - imm8 operands. 737 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::SUB) { 738 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 739 int RHSC = (int)RHS->getSExtValue(); 740 if (N.getOpcode() == ISD::SUB) 741 RHSC = -RHSC; 742 743 if ((RHSC >= -255) && (RHSC < 0)) { // 8 bits (always negative) 744 Base = N.getOperand(0); 745 if (Base.getOpcode() == ISD::FrameIndex) { 746 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 747 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 748 } 749 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 750 return true; 751 } 752 } 753 } 754 755 return false; 756} 757 758bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 759 SDValue &OffImm){ 760 unsigned Opcode = Op->getOpcode(); 761 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 762 ? cast<LoadSDNode>(Op)->getAddressingMode() 763 : cast<StoreSDNode>(Op)->getAddressingMode(); 764 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N)) { 765 int RHSC = (int)RHS->getZExtValue(); 766 if (RHSC >= 0 && RHSC < 0x100) { // 8 bits. 767 OffImm = ((AM == ISD::PRE_INC) || (AM == ISD::POST_INC)) 768 ? CurDAG->getTargetConstant(RHSC, MVT::i32) 769 : CurDAG->getTargetConstant(-RHSC, MVT::i32); 770 return true; 771 } 772 } 773 774 return false; 775} 776 777bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDNode *Op, SDValue N, 778 SDValue &Base, SDValue &OffImm) { 779 if (N.getOpcode() == ISD::ADD) { 780 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 781 int RHSC = (int)RHS->getZExtValue(); 782 if (((RHSC & 0x3) == 0) && 783 ((RHSC >= 0 && RHSC < 0x400) || (RHSC < 0 && RHSC > -0x400))) { // 8 bits. 784 Base = N.getOperand(0); 785 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 786 return true; 787 } 788 } 789 } else if (N.getOpcode() == ISD::SUB) { 790 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 791 int RHSC = (int)RHS->getZExtValue(); 792 if (((RHSC & 0x3) == 0) && (RHSC >= 0 && RHSC < 0x400)) { // 8 bits. 793 Base = N.getOperand(0); 794 OffImm = CurDAG->getTargetConstant(-RHSC, MVT::i32); 795 return true; 796 } 797 } 798 } 799 800 return false; 801} 802 803bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDNode *Op, SDValue N, 804 SDValue &Base, 805 SDValue &OffReg, SDValue &ShImm) { 806 // (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12. 807 if (N.getOpcode() != ISD::ADD) 808 return false; 809 810 // Leave (R + imm12) for t2LDRi12, (R - imm8) for t2LDRi8. 811 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 812 int RHSC = (int)RHS->getZExtValue(); 813 if (RHSC >= 0 && RHSC < 0x1000) // 12 bits (unsigned) 814 return false; 815 else if (RHSC < 0 && RHSC >= -255) // 8 bits 816 return false; 817 } 818 819 // Look for (R + R) or (R + (R << [1,2,3])). 820 unsigned ShAmt = 0; 821 Base = N.getOperand(0); 822 OffReg = N.getOperand(1); 823 824 // Swap if it is ((R << c) + R). 825 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg); 826 if (ShOpcVal != ARM_AM::lsl) { 827 ShOpcVal = ARM_AM::getShiftOpcForNode(Base); 828 if (ShOpcVal == ARM_AM::lsl) 829 std::swap(Base, OffReg); 830 } 831 832 if (ShOpcVal == ARM_AM::lsl) { 833 // Check to see if the RHS of the shift is a constant, if not, we can't fold 834 // it. 835 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(OffReg.getOperand(1))) { 836 ShAmt = Sh->getZExtValue(); 837 if (ShAmt >= 4) { 838 ShAmt = 0; 839 ShOpcVal = ARM_AM::no_shift; 840 } else 841 OffReg = OffReg.getOperand(0); 842 } else { 843 ShOpcVal = ARM_AM::no_shift; 844 } 845 } 846 847 ShImm = CurDAG->getTargetConstant(ShAmt, MVT::i32); 848 849 return true; 850} 851 852//===--------------------------------------------------------------------===// 853 854/// getAL - Returns a ARMCC::AL immediate node. 855static inline SDValue getAL(SelectionDAG *CurDAG) { 856 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32); 857} 858 859SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDNode *N) { 860 LoadSDNode *LD = cast<LoadSDNode>(N); 861 ISD::MemIndexedMode AM = LD->getAddressingMode(); 862 if (AM == ISD::UNINDEXED) 863 return NULL; 864 865 EVT LoadedVT = LD->getMemoryVT(); 866 SDValue Offset, AMOpc; 867 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 868 unsigned Opcode = 0; 869 bool Match = false; 870 if (LoadedVT == MVT::i32 && 871 SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { 872 Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST; 873 Match = true; 874 } else if (LoadedVT == MVT::i16 && 875 SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 876 Match = true; 877 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) 878 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) 879 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); 880 } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) { 881 if (LD->getExtensionType() == ISD::SEXTLOAD) { 882 if (SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 883 Match = true; 884 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; 885 } 886 } else { 887 if (SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { 888 Match = true; 889 Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST; 890 } 891 } 892 } 893 894 if (Match) { 895 SDValue Chain = LD->getChain(); 896 SDValue Base = LD->getBasePtr(); 897 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), 898 CurDAG->getRegister(0, MVT::i32), Chain }; 899 return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32, 900 MVT::Other, Ops, 6); 901 } 902 903 return NULL; 904} 905 906SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) { 907 LoadSDNode *LD = cast<LoadSDNode>(N); 908 ISD::MemIndexedMode AM = LD->getAddressingMode(); 909 if (AM == ISD::UNINDEXED) 910 return NULL; 911 912 EVT LoadedVT = LD->getMemoryVT(); 913 bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD; 914 SDValue Offset; 915 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 916 unsigned Opcode = 0; 917 bool Match = false; 918 if (SelectT2AddrModeImm8Offset(N, LD->getOffset(), Offset)) { 919 switch (LoadedVT.getSimpleVT().SimpleTy) { 920 case MVT::i32: 921 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST; 922 break; 923 case MVT::i16: 924 if (isSExtLd) 925 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST; 926 else 927 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST; 928 break; 929 case MVT::i8: 930 case MVT::i1: 931 if (isSExtLd) 932 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST; 933 else 934 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST; 935 break; 936 default: 937 return NULL; 938 } 939 Match = true; 940 } 941 942 if (Match) { 943 SDValue Chain = LD->getChain(); 944 SDValue Base = LD->getBasePtr(); 945 SDValue Ops[]= { Base, Offset, getAL(CurDAG), 946 CurDAG->getRegister(0, MVT::i32), Chain }; 947 return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32, 948 MVT::Other, Ops, 5); 949 } 950 951 return NULL; 952} 953 954SDNode *ARMDAGToDAGISel::SelectDYN_ALLOC(SDNode *N) { 955 DebugLoc dl = N->getDebugLoc(); 956 EVT VT = N->getValueType(0); 957 SDValue Chain = N->getOperand(0); 958 SDValue Size = N->getOperand(1); 959 SDValue Align = N->getOperand(2); 960 SDValue SP = CurDAG->getRegister(ARM::SP, MVT::i32); 961 int32_t AlignVal = cast<ConstantSDNode>(Align)->getSExtValue(); 962 if (AlignVal < 0) 963 // We need to align the stack. Use Thumb1 tAND which is the only thumb 964 // instruction that can read and write SP. This matches to a pseudo 965 // instruction that has a chain to ensure the result is written back to 966 // the stack pointer. 967 SP = SDValue(CurDAG->getMachineNode(ARM::tANDsp, dl, VT, SP, Align), 0); 968 969 bool isC = isa<ConstantSDNode>(Size); 970 uint32_t C = isC ? cast<ConstantSDNode>(Size)->getZExtValue() : ~0UL; 971 // Handle the most common case for both Thumb1 and Thumb2: 972 // tSUBspi - immediate is between 0 ... 508 inclusive. 973 if (C <= 508 && ((C & 3) == 0)) 974 // FIXME: tSUBspi encode scale 4 implicitly. 975 return CurDAG->SelectNodeTo(N, ARM::tSUBspi_, VT, MVT::Other, SP, 976 CurDAG->getTargetConstant(C/4, MVT::i32), 977 Chain); 978 979 if (Subtarget->isThumb1Only()) { 980 // Use tADDspr since Thumb1 does not have a sub r, sp, r. ARMISelLowering 981 // should have negated the size operand already. FIXME: We can't insert 982 // new target independent node at this stage so we are forced to negate 983 // it earlier. Is there a better solution? 984 return CurDAG->SelectNodeTo(N, ARM::tADDspr_, VT, MVT::Other, SP, Size, 985 Chain); 986 } else if (Subtarget->isThumb2()) { 987 if (isC && Predicate_t2_so_imm(Size.getNode())) { 988 // t2SUBrSPi 989 SDValue Ops[] = { SP, CurDAG->getTargetConstant(C, MVT::i32), Chain }; 990 return CurDAG->SelectNodeTo(N, ARM::t2SUBrSPi_, VT, MVT::Other, Ops, 3); 991 } else if (isC && Predicate_imm0_4095(Size.getNode())) { 992 // t2SUBrSPi12 993 SDValue Ops[] = { SP, CurDAG->getTargetConstant(C, MVT::i32), Chain }; 994 return CurDAG->SelectNodeTo(N, ARM::t2SUBrSPi12_, VT, MVT::Other, Ops, 3); 995 } else { 996 // t2SUBrSPs 997 SDValue Ops[] = { SP, Size, 998 getI32Imm(ARM_AM::getSORegOpc(ARM_AM::lsl,0)), Chain }; 999 return CurDAG->SelectNodeTo(N, ARM::t2SUBrSPs_, VT, MVT::Other, Ops, 4); 1000 } 1001 } 1002 1003 // FIXME: Add ADD / SUB sp instructions for ARM. 1004 return 0; 1005} 1006 1007/// PairDRegs - Insert a pair of double registers into an implicit def to 1008/// form a quad register. 1009SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) { 1010 DebugLoc dl = V0.getNode()->getDebugLoc(); 1011 SDValue Undef = 1012 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0); 1013 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::DSUBREG_0, MVT::i32); 1014 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::DSUBREG_1, MVT::i32); 1015 SDNode *Pair = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, 1016 VT, Undef, V0, SubReg0); 1017 return CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, 1018 VT, SDValue(Pair, 0), V1, SubReg1); 1019} 1020 1021/// GetNEONSubregVT - Given a type for a 128-bit NEON vector, return the type 1022/// for a 64-bit subregister of the vector. 1023static EVT GetNEONSubregVT(EVT VT) { 1024 switch (VT.getSimpleVT().SimpleTy) { 1025 default: llvm_unreachable("unhandled NEON type"); 1026 case MVT::v16i8: return MVT::v8i8; 1027 case MVT::v8i16: return MVT::v4i16; 1028 case MVT::v4f32: return MVT::v2f32; 1029 case MVT::v4i32: return MVT::v2i32; 1030 case MVT::v2i64: return MVT::v1i64; 1031 } 1032} 1033 1034SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs, 1035 unsigned *DOpcodes, unsigned *QOpcodes0, 1036 unsigned *QOpcodes1) { 1037 assert(NumVecs >=2 && NumVecs <= 4 && "VLD NumVecs out-of-range"); 1038 DebugLoc dl = N->getDebugLoc(); 1039 1040 SDValue MemAddr, MemUpdate, MemOpc, Align; 1041 if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align)) 1042 return NULL; 1043 1044 SDValue Chain = N->getOperand(0); 1045 EVT VT = N->getValueType(0); 1046 bool is64BitVector = VT.is64BitVector(); 1047 1048 unsigned OpcodeIndex; 1049 switch (VT.getSimpleVT().SimpleTy) { 1050 default: llvm_unreachable("unhandled vld type"); 1051 // Double-register operations: 1052 case MVT::v8i8: OpcodeIndex = 0; break; 1053 case MVT::v4i16: OpcodeIndex = 1; break; 1054 case MVT::v2f32: 1055 case MVT::v2i32: OpcodeIndex = 2; break; 1056 case MVT::v1i64: OpcodeIndex = 3; break; 1057 // Quad-register operations: 1058 case MVT::v16i8: OpcodeIndex = 0; break; 1059 case MVT::v8i16: OpcodeIndex = 1; break; 1060 case MVT::v4f32: 1061 case MVT::v4i32: OpcodeIndex = 2; break; 1062 } 1063 1064 SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); 1065 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1066 if (is64BitVector) { 1067 unsigned Opc = DOpcodes[OpcodeIndex]; 1068 const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, 1069 Pred, PredReg, Chain }; 1070 std::vector<EVT> ResTys(NumVecs, VT); 1071 ResTys.push_back(MVT::Other); 1072 return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 7); 1073 } 1074 1075 EVT RegVT = GetNEONSubregVT(VT); 1076 if (NumVecs == 2) { 1077 // Quad registers are directly supported for VLD2, 1078 // loading 2 pairs of D regs. 1079 unsigned Opc = QOpcodes0[OpcodeIndex]; 1080 const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, 1081 Pred, PredReg, Chain }; 1082 std::vector<EVT> ResTys(4, VT); 1083 ResTys.push_back(MVT::Other); 1084 SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 7); 1085 Chain = SDValue(VLd, 4); 1086 1087 // Combine the even and odd subregs to produce the result. 1088 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1089 SDNode *Q = PairDRegs(VT, SDValue(VLd, 2*Vec), SDValue(VLd, 2*Vec+1)); 1090 ReplaceUses(SDValue(N, Vec), SDValue(Q, 0)); 1091 } 1092 } else { 1093 // Otherwise, quad registers are loaded with two separate instructions, 1094 // where one loads the even registers and the other loads the odd registers. 1095 1096 // Enable writeback to the address register. 1097 MemOpc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(true), MVT::i32); 1098 1099 std::vector<EVT> ResTys(NumVecs, RegVT); 1100 ResTys.push_back(MemAddr.getValueType()); 1101 ResTys.push_back(MVT::Other); 1102 1103 // Load the even subregs. 1104 unsigned Opc = QOpcodes0[OpcodeIndex]; 1105 const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, Align, 1106 Pred, PredReg, Chain }; 1107 SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 7); 1108 Chain = SDValue(VLdA, NumVecs+1); 1109 1110 // Load the odd subregs. 1111 Opc = QOpcodes1[OpcodeIndex]; 1112 const SDValue OpsB[] = { SDValue(VLdA, NumVecs), MemUpdate, MemOpc, 1113 Align, Pred, PredReg, Chain }; 1114 SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 7); 1115 Chain = SDValue(VLdB, NumVecs+1); 1116 1117 // Combine the even and odd subregs to produce the result. 1118 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1119 SDNode *Q = PairDRegs(VT, SDValue(VLdA, Vec), SDValue(VLdB, Vec)); 1120 ReplaceUses(SDValue(N, Vec), SDValue(Q, 0)); 1121 } 1122 } 1123 ReplaceUses(SDValue(N, NumVecs), Chain); 1124 return NULL; 1125} 1126 1127SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs, 1128 unsigned *DOpcodes, unsigned *QOpcodes0, 1129 unsigned *QOpcodes1) { 1130 assert(NumVecs >=2 && NumVecs <= 4 && "VST NumVecs out-of-range"); 1131 DebugLoc dl = N->getDebugLoc(); 1132 1133 SDValue MemAddr, MemUpdate, MemOpc, Align; 1134 if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align)) 1135 return NULL; 1136 1137 SDValue Chain = N->getOperand(0); 1138 EVT VT = N->getOperand(3).getValueType(); 1139 bool is64BitVector = VT.is64BitVector(); 1140 1141 unsigned OpcodeIndex; 1142 switch (VT.getSimpleVT().SimpleTy) { 1143 default: llvm_unreachable("unhandled vst type"); 1144 // Double-register operations: 1145 case MVT::v8i8: OpcodeIndex = 0; break; 1146 case MVT::v4i16: OpcodeIndex = 1; break; 1147 case MVT::v2f32: 1148 case MVT::v2i32: OpcodeIndex = 2; break; 1149 case MVT::v1i64: OpcodeIndex = 3; break; 1150 // Quad-register operations: 1151 case MVT::v16i8: OpcodeIndex = 0; break; 1152 case MVT::v8i16: OpcodeIndex = 1; break; 1153 case MVT::v4f32: 1154 case MVT::v4i32: OpcodeIndex = 2; break; 1155 } 1156 1157 SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); 1158 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1159 1160 SmallVector<SDValue, 8> Ops; 1161 Ops.push_back(MemAddr); 1162 Ops.push_back(MemUpdate); 1163 Ops.push_back(MemOpc); 1164 Ops.push_back(Align); 1165 1166 if (is64BitVector) { 1167 unsigned Opc = DOpcodes[OpcodeIndex]; 1168 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1169 Ops.push_back(N->getOperand(Vec+3)); 1170 Ops.push_back(Pred); 1171 Ops.push_back(PredReg); 1172 Ops.push_back(Chain); 1173 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+7); 1174 } 1175 1176 EVT RegVT = GetNEONSubregVT(VT); 1177 if (NumVecs == 2) { 1178 // Quad registers are directly supported for VST2, 1179 // storing 2 pairs of D regs. 1180 unsigned Opc = QOpcodes0[OpcodeIndex]; 1181 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1182 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT, 1183 N->getOperand(Vec+3))); 1184 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, 1185 N->getOperand(Vec+3))); 1186 } 1187 Ops.push_back(Pred); 1188 Ops.push_back(PredReg); 1189 Ops.push_back(Chain); 1190 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 11); 1191 } 1192 1193 // Otherwise, quad registers are stored with two separate instructions, 1194 // where one stores the even registers and the other stores the odd registers. 1195 1196 // Enable writeback to the address register. 1197 MemOpc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(true), MVT::i32); 1198 1199 // Store the even subregs. 1200 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1201 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT, 1202 N->getOperand(Vec+3))); 1203 Ops.push_back(Pred); 1204 Ops.push_back(PredReg); 1205 Ops.push_back(Chain); 1206 unsigned Opc = QOpcodes0[OpcodeIndex]; 1207 SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(), 1208 MVT::Other, Ops.data(), NumVecs+7); 1209 Chain = SDValue(VStA, 1); 1210 1211 // Store the odd subregs. 1212 Ops[0] = SDValue(VStA, 0); // MemAddr 1213 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1214 Ops[Vec+4] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, 1215 N->getOperand(Vec+3)); 1216 Ops[NumVecs+4] = Pred; 1217 Ops[NumVecs+5] = PredReg; 1218 Ops[NumVecs+6] = Chain; 1219 Opc = QOpcodes1[OpcodeIndex]; 1220 SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(), 1221 MVT::Other, Ops.data(), NumVecs+7); 1222 Chain = SDValue(VStB, 1); 1223 ReplaceUses(SDValue(N, 0), Chain); 1224 return NULL; 1225} 1226 1227SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad, 1228 unsigned NumVecs, unsigned *DOpcodes, 1229 unsigned *QOpcodes0, 1230 unsigned *QOpcodes1) { 1231 assert(NumVecs >=2 && NumVecs <= 4 && "VLDSTLane NumVecs out-of-range"); 1232 DebugLoc dl = N->getDebugLoc(); 1233 1234 SDValue MemAddr, MemUpdate, MemOpc, Align; 1235 if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align)) 1236 return NULL; 1237 1238 SDValue Chain = N->getOperand(0); 1239 unsigned Lane = 1240 cast<ConstantSDNode>(N->getOperand(NumVecs+3))->getZExtValue(); 1241 EVT VT = IsLoad ? N->getValueType(0) : N->getOperand(3).getValueType(); 1242 bool is64BitVector = VT.is64BitVector(); 1243 1244 // Quad registers are handled by load/store of subregs. Find the subreg info. 1245 unsigned NumElts = 0; 1246 int SubregIdx = 0; 1247 EVT RegVT = VT; 1248 if (!is64BitVector) { 1249 RegVT = GetNEONSubregVT(VT); 1250 NumElts = RegVT.getVectorNumElements(); 1251 SubregIdx = (Lane < NumElts) ? ARM::DSUBREG_0 : ARM::DSUBREG_1; 1252 } 1253 1254 unsigned OpcodeIndex; 1255 switch (VT.getSimpleVT().SimpleTy) { 1256 default: llvm_unreachable("unhandled vld/vst lane type"); 1257 // Double-register operations: 1258 case MVT::v8i8: OpcodeIndex = 0; break; 1259 case MVT::v4i16: OpcodeIndex = 1; break; 1260 case MVT::v2f32: 1261 case MVT::v2i32: OpcodeIndex = 2; break; 1262 // Quad-register operations: 1263 case MVT::v8i16: OpcodeIndex = 0; break; 1264 case MVT::v4f32: 1265 case MVT::v4i32: OpcodeIndex = 1; break; 1266 } 1267 1268 SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); 1269 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1270 1271 SmallVector<SDValue, 9> Ops; 1272 Ops.push_back(MemAddr); 1273 Ops.push_back(MemUpdate); 1274 Ops.push_back(MemOpc); 1275 Ops.push_back(Align); 1276 1277 unsigned Opc = 0; 1278 if (is64BitVector) { 1279 Opc = DOpcodes[OpcodeIndex]; 1280 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1281 Ops.push_back(N->getOperand(Vec+3)); 1282 } else { 1283 // Check if this is loading the even or odd subreg of a Q register. 1284 if (Lane < NumElts) { 1285 Opc = QOpcodes0[OpcodeIndex]; 1286 } else { 1287 Lane -= NumElts; 1288 Opc = QOpcodes1[OpcodeIndex]; 1289 } 1290 // Extract the subregs of the input vector. 1291 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1292 Ops.push_back(CurDAG->getTargetExtractSubreg(SubregIdx, dl, RegVT, 1293 N->getOperand(Vec+3))); 1294 } 1295 Ops.push_back(getI32Imm(Lane)); 1296 Ops.push_back(Pred); 1297 Ops.push_back(PredReg); 1298 Ops.push_back(Chain); 1299 1300 if (!IsLoad) 1301 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+8); 1302 1303 std::vector<EVT> ResTys(NumVecs, RegVT); 1304 ResTys.push_back(MVT::Other); 1305 SDNode *VLdLn = 1306 CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+8); 1307 // For a 64-bit vector load to D registers, nothing more needs to be done. 1308 if (is64BitVector) 1309 return VLdLn; 1310 1311 // For 128-bit vectors, take the 64-bit results of the load and insert them 1312 // as subregs into the result. 1313 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1314 SDValue QuadVec = CurDAG->getTargetInsertSubreg(SubregIdx, dl, VT, 1315 N->getOperand(Vec+3), 1316 SDValue(VLdLn, Vec)); 1317 ReplaceUses(SDValue(N, Vec), QuadVec); 1318 } 1319 1320 Chain = SDValue(VLdLn, NumVecs); 1321 ReplaceUses(SDValue(N, NumVecs), Chain); 1322 return NULL; 1323} 1324 1325SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N, 1326 unsigned Opc) { 1327 if (!Subtarget->hasV6T2Ops()) 1328 return NULL; 1329 1330 unsigned Shl_imm = 0; 1331 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, Shl_imm)) { 1332 assert(Shl_imm > 0 && Shl_imm < 32 && "bad amount in shift node!"); 1333 unsigned Srl_imm = 0; 1334 if (isInt32Immediate(N->getOperand(1), Srl_imm)) { 1335 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 1336 unsigned Width = 32 - Srl_imm; 1337 int LSB = Srl_imm - Shl_imm; 1338 if (LSB < 0) 1339 return NULL; 1340 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1341 SDValue Ops[] = { N->getOperand(0).getOperand(0), 1342 CurDAG->getTargetConstant(LSB, MVT::i32), 1343 CurDAG->getTargetConstant(Width, MVT::i32), 1344 getAL(CurDAG), Reg0 }; 1345 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); 1346 } 1347 } 1348 return NULL; 1349} 1350 1351SDNode *ARMDAGToDAGISel:: 1352SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1353 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1354 SDValue CPTmp0; 1355 SDValue CPTmp1; 1356 if (SelectT2ShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1)) { 1357 unsigned SOVal = cast<ConstantSDNode>(CPTmp1)->getZExtValue(); 1358 unsigned SOShOp = ARM_AM::getSORegShOp(SOVal); 1359 unsigned Opc = 0; 1360 switch (SOShOp) { 1361 case ARM_AM::lsl: Opc = ARM::t2MOVCClsl; break; 1362 case ARM_AM::lsr: Opc = ARM::t2MOVCClsr; break; 1363 case ARM_AM::asr: Opc = ARM::t2MOVCCasr; break; 1364 case ARM_AM::ror: Opc = ARM::t2MOVCCror; break; 1365 default: 1366 llvm_unreachable("Unknown so_reg opcode!"); 1367 break; 1368 } 1369 SDValue SOShImm = 1370 CurDAG->getTargetConstant(ARM_AM::getSORegOffset(SOVal), MVT::i32); 1371 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1372 SDValue Ops[] = { FalseVal, CPTmp0, SOShImm, CC, CCR, InFlag }; 1373 return CurDAG->SelectNodeTo(N, Opc, MVT::i32,Ops, 6); 1374 } 1375 return 0; 1376} 1377 1378SDNode *ARMDAGToDAGISel:: 1379SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1380 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1381 SDValue CPTmp0; 1382 SDValue CPTmp1; 1383 SDValue CPTmp2; 1384 if (SelectShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1, CPTmp2)) { 1385 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1386 SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag }; 1387 return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7); 1388 } 1389 return 0; 1390} 1391 1392SDNode *ARMDAGToDAGISel:: 1393SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1394 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1395 ConstantSDNode *T = dyn_cast<ConstantSDNode>(TrueVal); 1396 if (!T) 1397 return 0; 1398 1399 if (Predicate_t2_so_imm(TrueVal.getNode())) { 1400 SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32); 1401 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1402 SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag }; 1403 return CurDAG->SelectNodeTo(N, 1404 ARM::t2MOVCCi, MVT::i32, Ops, 5); 1405 } 1406 return 0; 1407} 1408 1409SDNode *ARMDAGToDAGISel:: 1410SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1411 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1412 ConstantSDNode *T = dyn_cast<ConstantSDNode>(TrueVal); 1413 if (!T) 1414 return 0; 1415 1416 if (Predicate_so_imm(TrueVal.getNode())) { 1417 SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32); 1418 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1419 SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag }; 1420 return CurDAG->SelectNodeTo(N, 1421 ARM::MOVCCi, MVT::i32, Ops, 5); 1422 } 1423 return 0; 1424} 1425 1426SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDNode *N) { 1427 EVT VT = N->getValueType(0); 1428 SDValue FalseVal = N->getOperand(0); 1429 SDValue TrueVal = N->getOperand(1); 1430 SDValue CC = N->getOperand(2); 1431 SDValue CCR = N->getOperand(3); 1432 SDValue InFlag = N->getOperand(4); 1433 assert(CC.getOpcode() == ISD::Constant); 1434 assert(CCR.getOpcode() == ISD::Register); 1435 ARMCC::CondCodes CCVal = 1436 (ARMCC::CondCodes)cast<ConstantSDNode>(CC)->getZExtValue(); 1437 1438 if (!Subtarget->isThumb1Only() && VT == MVT::i32) { 1439 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1440 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1441 // Pattern complexity = 18 cost = 1 size = 0 1442 SDValue CPTmp0; 1443 SDValue CPTmp1; 1444 SDValue CPTmp2; 1445 if (Subtarget->isThumb()) { 1446 SDNode *Res = SelectT2CMOVShiftOp(N, FalseVal, TrueVal, 1447 CCVal, CCR, InFlag); 1448 if (!Res) 1449 Res = SelectT2CMOVShiftOp(N, TrueVal, FalseVal, 1450 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1451 if (Res) 1452 return Res; 1453 } else { 1454 SDNode *Res = SelectARMCMOVShiftOp(N, FalseVal, TrueVal, 1455 CCVal, CCR, InFlag); 1456 if (!Res) 1457 Res = SelectARMCMOVShiftOp(N, TrueVal, FalseVal, 1458 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1459 if (Res) 1460 return Res; 1461 } 1462 1463 // Pattern: (ARMcmov:i32 GPR:i32:$false, 1464 // (imm:i32)<<P:Predicate_so_imm>>:$true, 1465 // (imm:i32):$cc) 1466 // Emits: (MOVCCi:i32 GPR:i32:$false, 1467 // (so_imm:i32 (imm:i32):$true), (imm:i32):$cc) 1468 // Pattern complexity = 10 cost = 1 size = 0 1469 if (Subtarget->isThumb()) { 1470 SDNode *Res = SelectT2CMOVSoImmOp(N, FalseVal, TrueVal, 1471 CCVal, CCR, InFlag); 1472 if (!Res) 1473 Res = SelectT2CMOVSoImmOp(N, TrueVal, FalseVal, 1474 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1475 if (Res) 1476 return Res; 1477 } else { 1478 SDNode *Res = SelectARMCMOVSoImmOp(N, FalseVal, TrueVal, 1479 CCVal, CCR, InFlag); 1480 if (!Res) 1481 Res = SelectARMCMOVSoImmOp(N, TrueVal, FalseVal, 1482 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1483 if (Res) 1484 return Res; 1485 } 1486 } 1487 1488 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1489 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1490 // Pattern complexity = 6 cost = 1 size = 0 1491 // 1492 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1493 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1494 // Pattern complexity = 6 cost = 11 size = 0 1495 // 1496 // Also FCPYScc and FCPYDcc. 1497 SDValue Tmp2 = CurDAG->getTargetConstant(CCVal, MVT::i32); 1498 SDValue Ops[] = { FalseVal, TrueVal, Tmp2, CCR, InFlag }; 1499 unsigned Opc = 0; 1500 switch (VT.getSimpleVT().SimpleTy) { 1501 default: assert(false && "Illegal conditional move type!"); 1502 break; 1503 case MVT::i32: 1504 Opc = Subtarget->isThumb() 1505 ? (Subtarget->hasThumb2() ? ARM::t2MOVCCr : ARM::tMOVCCr_pseudo) 1506 : ARM::MOVCCr; 1507 break; 1508 case MVT::f32: 1509 Opc = ARM::VMOVScc; 1510 break; 1511 case MVT::f64: 1512 Opc = ARM::VMOVDcc; 1513 break; 1514 } 1515 return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5); 1516} 1517 1518SDNode *ARMDAGToDAGISel::Select(SDNode *N) { 1519 DebugLoc dl = N->getDebugLoc(); 1520 1521 if (N->isMachineOpcode()) 1522 return NULL; // Already selected. 1523 1524 switch (N->getOpcode()) { 1525 default: break; 1526 case ISD::Constant: { 1527 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 1528 bool UseCP = true; 1529 if (Subtarget->hasThumb2()) 1530 // Thumb2-aware targets have the MOVT instruction, so all immediates can 1531 // be done with MOV + MOVT, at worst. 1532 UseCP = 0; 1533 else { 1534 if (Subtarget->isThumb()) { 1535 UseCP = (Val > 255 && // MOV 1536 ~Val > 255 && // MOV + MVN 1537 !ARM_AM::isThumbImmShiftedVal(Val)); // MOV + LSL 1538 } else 1539 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV 1540 ARM_AM::getSOImmVal(~Val) == -1 && // MVN 1541 !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs. 1542 } 1543 1544 if (UseCP) { 1545 SDValue CPIdx = 1546 CurDAG->getTargetConstantPool(ConstantInt::get( 1547 Type::getInt32Ty(*CurDAG->getContext()), Val), 1548 TLI.getPointerTy()); 1549 1550 SDNode *ResNode; 1551 if (Subtarget->isThumb1Only()) { 1552 SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); 1553 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1554 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() }; 1555 ResNode = CurDAG->getMachineNode(ARM::tLDRcp, dl, MVT::i32, MVT::Other, 1556 Ops, 4); 1557 } else { 1558 SDValue Ops[] = { 1559 CPIdx, 1560 CurDAG->getRegister(0, MVT::i32), 1561 CurDAG->getTargetConstant(0, MVT::i32), 1562 getAL(CurDAG), 1563 CurDAG->getRegister(0, MVT::i32), 1564 CurDAG->getEntryNode() 1565 }; 1566 ResNode=CurDAG->getMachineNode(ARM::LDRcp, dl, MVT::i32, MVT::Other, 1567 Ops, 6); 1568 } 1569 ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0)); 1570 return NULL; 1571 } 1572 1573 // Other cases are autogenerated. 1574 break; 1575 } 1576 case ISD::FrameIndex: { 1577 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. 1578 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1579 SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 1580 if (Subtarget->isThumb1Only()) { 1581 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI, 1582 CurDAG->getTargetConstant(0, MVT::i32)); 1583 } else { 1584 unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ? 1585 ARM::t2ADDri : ARM::ADDri); 1586 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), 1587 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1588 CurDAG->getRegister(0, MVT::i32) }; 1589 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); 1590 } 1591 } 1592 case ARMISD::DYN_ALLOC: 1593 return SelectDYN_ALLOC(N); 1594 case ISD::SRL: 1595 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, 1596 Subtarget->isThumb() ? ARM::t2UBFX : ARM::UBFX)) 1597 return I; 1598 break; 1599 case ISD::SRA: 1600 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, 1601 Subtarget->isThumb() ? ARM::t2SBFX : ARM::SBFX)) 1602 return I; 1603 break; 1604 case ISD::MUL: 1605 if (Subtarget->isThumb1Only()) 1606 break; 1607 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) { 1608 unsigned RHSV = C->getZExtValue(); 1609 if (!RHSV) break; 1610 if (isPowerOf2_32(RHSV-1)) { // 2^n+1? 1611 unsigned ShImm = Log2_32(RHSV-1); 1612 if (ShImm >= 32) 1613 break; 1614 SDValue V = N->getOperand(0); 1615 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 1616 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); 1617 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1618 if (Subtarget->isThumb()) { 1619 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1620 return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops, 6); 1621 } else { 1622 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1623 return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7); 1624 } 1625 } 1626 if (isPowerOf2_32(RHSV+1)) { // 2^n-1? 1627 unsigned ShImm = Log2_32(RHSV+1); 1628 if (ShImm >= 32) 1629 break; 1630 SDValue V = N->getOperand(0); 1631 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 1632 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); 1633 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1634 if (Subtarget->isThumb()) { 1635 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0 }; 1636 return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops, 5); 1637 } else { 1638 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1639 return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7); 1640 } 1641 } 1642 } 1643 break; 1644 case ISD::AND: { 1645 // (and (or x, c2), c1) and top 16-bits of c1 and c2 match, lower 16-bits 1646 // of c1 are 0xffff, and lower 16-bit of c2 are 0. That is, the top 16-bits 1647 // are entirely contributed by c2 and lower 16-bits are entirely contributed 1648 // by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)). 1649 // Select it to: "movt x, ((c1 & 0xffff) >> 16) 1650 EVT VT = N->getValueType(0); 1651 if (VT != MVT::i32) 1652 break; 1653 unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2()) 1654 ? ARM::t2MOVTi16 1655 : (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0); 1656 if (!Opc) 1657 break; 1658 SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); 1659 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 1660 if (!N1C) 1661 break; 1662 if (N0.getOpcode() == ISD::OR && N0.getNode()->hasOneUse()) { 1663 SDValue N2 = N0.getOperand(1); 1664 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2); 1665 if (!N2C) 1666 break; 1667 unsigned N1CVal = N1C->getZExtValue(); 1668 unsigned N2CVal = N2C->getZExtValue(); 1669 if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) && 1670 (N1CVal & 0xffffU) == 0xffffU && 1671 (N2CVal & 0xffffU) == 0x0U) { 1672 SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16, 1673 MVT::i32); 1674 SDValue Ops[] = { N0.getOperand(0), Imm16, 1675 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; 1676 return CurDAG->getMachineNode(Opc, dl, VT, Ops, 4); 1677 } 1678 } 1679 break; 1680 } 1681 case ARMISD::VMOVRRD: 1682 return CurDAG->getMachineNode(ARM::VMOVRRD, dl, MVT::i32, MVT::i32, 1683 N->getOperand(0), getAL(CurDAG), 1684 CurDAG->getRegister(0, MVT::i32)); 1685 case ISD::UMUL_LOHI: { 1686 if (Subtarget->isThumb1Only()) 1687 break; 1688 if (Subtarget->isThumb()) { 1689 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 1690 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1691 CurDAG->getRegister(0, MVT::i32) }; 1692 return CurDAG->getMachineNode(ARM::t2UMULL, dl, MVT::i32, MVT::i32, Ops,4); 1693 } else { 1694 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 1695 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1696 CurDAG->getRegister(0, MVT::i32) }; 1697 return CurDAG->getMachineNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5); 1698 } 1699 } 1700 case ISD::SMUL_LOHI: { 1701 if (Subtarget->isThumb1Only()) 1702 break; 1703 if (Subtarget->isThumb()) { 1704 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 1705 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; 1706 return CurDAG->getMachineNode(ARM::t2SMULL, dl, MVT::i32, MVT::i32, Ops,4); 1707 } else { 1708 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 1709 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1710 CurDAG->getRegister(0, MVT::i32) }; 1711 return CurDAG->getMachineNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5); 1712 } 1713 } 1714 case ISD::LOAD: { 1715 SDNode *ResNode = 0; 1716 if (Subtarget->isThumb() && Subtarget->hasThumb2()) 1717 ResNode = SelectT2IndexedLoad(N); 1718 else 1719 ResNode = SelectARMIndexedLoad(N); 1720 if (ResNode) 1721 return ResNode; 1722 // Other cases are autogenerated. 1723 break; 1724 } 1725 case ARMISD::BRCOND: { 1726 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1727 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc) 1728 // Pattern complexity = 6 cost = 1 size = 0 1729 1730 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1731 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc) 1732 // Pattern complexity = 6 cost = 1 size = 0 1733 1734 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1735 // Emits: (t2Bcc:void (bb:Other):$dst, (imm:i32):$cc) 1736 // Pattern complexity = 6 cost = 1 size = 0 1737 1738 unsigned Opc = Subtarget->isThumb() ? 1739 ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; 1740 SDValue Chain = N->getOperand(0); 1741 SDValue N1 = N->getOperand(1); 1742 SDValue N2 = N->getOperand(2); 1743 SDValue N3 = N->getOperand(3); 1744 SDValue InFlag = N->getOperand(4); 1745 assert(N1.getOpcode() == ISD::BasicBlock); 1746 assert(N2.getOpcode() == ISD::Constant); 1747 assert(N3.getOpcode() == ISD::Register); 1748 1749 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1750 cast<ConstantSDNode>(N2)->getZExtValue()), 1751 MVT::i32); 1752 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; 1753 SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, 1754 MVT::Flag, Ops, 5); 1755 Chain = SDValue(ResNode, 0); 1756 if (N->getNumValues() == 2) { 1757 InFlag = SDValue(ResNode, 1); 1758 ReplaceUses(SDValue(N, 1), InFlag); 1759 } 1760 ReplaceUses(SDValue(N, 0), 1761 SDValue(Chain.getNode(), Chain.getResNo())); 1762 return NULL; 1763 } 1764 case ARMISD::CMOV: 1765 return SelectCMOVOp(N); 1766 case ARMISD::CNEG: { 1767 EVT VT = N->getValueType(0); 1768 SDValue N0 = N->getOperand(0); 1769 SDValue N1 = N->getOperand(1); 1770 SDValue N2 = N->getOperand(2); 1771 SDValue N3 = N->getOperand(3); 1772 SDValue InFlag = N->getOperand(4); 1773 assert(N2.getOpcode() == ISD::Constant); 1774 assert(N3.getOpcode() == ISD::Register); 1775 1776 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1777 cast<ConstantSDNode>(N2)->getZExtValue()), 1778 MVT::i32); 1779 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 1780 unsigned Opc = 0; 1781 switch (VT.getSimpleVT().SimpleTy) { 1782 default: assert(false && "Illegal conditional move type!"); 1783 break; 1784 case MVT::f32: 1785 Opc = ARM::VNEGScc; 1786 break; 1787 case MVT::f64: 1788 Opc = ARM::VNEGDcc; 1789 break; 1790 } 1791 return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5); 1792 } 1793 1794 case ARMISD::VZIP: { 1795 unsigned Opc = 0; 1796 EVT VT = N->getValueType(0); 1797 switch (VT.getSimpleVT().SimpleTy) { 1798 default: return NULL; 1799 case MVT::v8i8: Opc = ARM::VZIPd8; break; 1800 case MVT::v4i16: Opc = ARM::VZIPd16; break; 1801 case MVT::v2f32: 1802 case MVT::v2i32: Opc = ARM::VZIPd32; break; 1803 case MVT::v16i8: Opc = ARM::VZIPq8; break; 1804 case MVT::v8i16: Opc = ARM::VZIPq16; break; 1805 case MVT::v4f32: 1806 case MVT::v4i32: Opc = ARM::VZIPq32; break; 1807 } 1808 SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); 1809 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1810 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 1811 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); 1812 } 1813 case ARMISD::VUZP: { 1814 unsigned Opc = 0; 1815 EVT VT = N->getValueType(0); 1816 switch (VT.getSimpleVT().SimpleTy) { 1817 default: return NULL; 1818 case MVT::v8i8: Opc = ARM::VUZPd8; break; 1819 case MVT::v4i16: Opc = ARM::VUZPd16; break; 1820 case MVT::v2f32: 1821 case MVT::v2i32: Opc = ARM::VUZPd32; break; 1822 case MVT::v16i8: Opc = ARM::VUZPq8; break; 1823 case MVT::v8i16: Opc = ARM::VUZPq16; break; 1824 case MVT::v4f32: 1825 case MVT::v4i32: Opc = ARM::VUZPq32; break; 1826 } 1827 SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); 1828 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1829 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 1830 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); 1831 } 1832 case ARMISD::VTRN: { 1833 unsigned Opc = 0; 1834 EVT VT = N->getValueType(0); 1835 switch (VT.getSimpleVT().SimpleTy) { 1836 default: return NULL; 1837 case MVT::v8i8: Opc = ARM::VTRNd8; break; 1838 case MVT::v4i16: Opc = ARM::VTRNd16; break; 1839 case MVT::v2f32: 1840 case MVT::v2i32: Opc = ARM::VTRNd32; break; 1841 case MVT::v16i8: Opc = ARM::VTRNq8; break; 1842 case MVT::v8i16: Opc = ARM::VTRNq16; break; 1843 case MVT::v4f32: 1844 case MVT::v4i32: Opc = ARM::VTRNq32; break; 1845 } 1846 SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); 1847 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1848 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 1849 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); 1850 } 1851 1852 case ISD::INTRINSIC_VOID: 1853 case ISD::INTRINSIC_W_CHAIN: { 1854 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 1855 switch (IntNo) { 1856 default: 1857 break; 1858 1859 case Intrinsic::arm_neon_vld2: { 1860 unsigned DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16, 1861 ARM::VLD2d32, ARM::VLD2d64 }; 1862 unsigned QOpcodes[] = { ARM::VLD2q8, ARM::VLD2q16, ARM::VLD2q32 }; 1863 return SelectVLD(N, 2, DOpcodes, QOpcodes, 0); 1864 } 1865 1866 case Intrinsic::arm_neon_vld3: { 1867 unsigned DOpcodes[] = { ARM::VLD3d8, ARM::VLD3d16, 1868 ARM::VLD3d32, ARM::VLD3d64 }; 1869 unsigned QOpcodes0[] = { ARM::VLD3q8a, ARM::VLD3q16a, ARM::VLD3q32a }; 1870 unsigned QOpcodes1[] = { ARM::VLD3q8b, ARM::VLD3q16b, ARM::VLD3q32b }; 1871 return SelectVLD(N, 3, DOpcodes, QOpcodes0, QOpcodes1); 1872 } 1873 1874 case Intrinsic::arm_neon_vld4: { 1875 unsigned DOpcodes[] = { ARM::VLD4d8, ARM::VLD4d16, 1876 ARM::VLD4d32, ARM::VLD4d64 }; 1877 unsigned QOpcodes0[] = { ARM::VLD4q8a, ARM::VLD4q16a, ARM::VLD4q32a }; 1878 unsigned QOpcodes1[] = { ARM::VLD4q8b, ARM::VLD4q16b, ARM::VLD4q32b }; 1879 return SelectVLD(N, 4, DOpcodes, QOpcodes0, QOpcodes1); 1880 } 1881 1882 case Intrinsic::arm_neon_vld2lane: { 1883 unsigned DOpcodes[] = { ARM::VLD2LNd8, ARM::VLD2LNd16, ARM::VLD2LNd32 }; 1884 unsigned QOpcodes0[] = { ARM::VLD2LNq16a, ARM::VLD2LNq32a }; 1885 unsigned QOpcodes1[] = { ARM::VLD2LNq16b, ARM::VLD2LNq32b }; 1886 return SelectVLDSTLane(N, true, 2, DOpcodes, QOpcodes0, QOpcodes1); 1887 } 1888 1889 case Intrinsic::arm_neon_vld3lane: { 1890 unsigned DOpcodes[] = { ARM::VLD3LNd8, ARM::VLD3LNd16, ARM::VLD3LNd32 }; 1891 unsigned QOpcodes0[] = { ARM::VLD3LNq16a, ARM::VLD3LNq32a }; 1892 unsigned QOpcodes1[] = { ARM::VLD3LNq16b, ARM::VLD3LNq32b }; 1893 return SelectVLDSTLane(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1); 1894 } 1895 1896 case Intrinsic::arm_neon_vld4lane: { 1897 unsigned DOpcodes[] = { ARM::VLD4LNd8, ARM::VLD4LNd16, ARM::VLD4LNd32 }; 1898 unsigned QOpcodes0[] = { ARM::VLD4LNq16a, ARM::VLD4LNq32a }; 1899 unsigned QOpcodes1[] = { ARM::VLD4LNq16b, ARM::VLD4LNq32b }; 1900 return SelectVLDSTLane(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1); 1901 } 1902 1903 case Intrinsic::arm_neon_vst2: { 1904 unsigned DOpcodes[] = { ARM::VST2d8, ARM::VST2d16, 1905 ARM::VST2d32, ARM::VST2d64 }; 1906 unsigned QOpcodes[] = { ARM::VST2q8, ARM::VST2q16, ARM::VST2q32 }; 1907 return SelectVST(N, 2, DOpcodes, QOpcodes, 0); 1908 } 1909 1910 case Intrinsic::arm_neon_vst3: { 1911 unsigned DOpcodes[] = { ARM::VST3d8, ARM::VST3d16, 1912 ARM::VST3d32, ARM::VST3d64 }; 1913 unsigned QOpcodes0[] = { ARM::VST3q8a, ARM::VST3q16a, ARM::VST3q32a }; 1914 unsigned QOpcodes1[] = { ARM::VST3q8b, ARM::VST3q16b, ARM::VST3q32b }; 1915 return SelectVST(N, 3, DOpcodes, QOpcodes0, QOpcodes1); 1916 } 1917 1918 case Intrinsic::arm_neon_vst4: { 1919 unsigned DOpcodes[] = { ARM::VST4d8, ARM::VST4d16, 1920 ARM::VST4d32, ARM::VST4d64 }; 1921 unsigned QOpcodes0[] = { ARM::VST4q8a, ARM::VST4q16a, ARM::VST4q32a }; 1922 unsigned QOpcodes1[] = { ARM::VST4q8b, ARM::VST4q16b, ARM::VST4q32b }; 1923 return SelectVST(N, 4, DOpcodes, QOpcodes0, QOpcodes1); 1924 } 1925 1926 case Intrinsic::arm_neon_vst2lane: { 1927 unsigned DOpcodes[] = { ARM::VST2LNd8, ARM::VST2LNd16, ARM::VST2LNd32 }; 1928 unsigned QOpcodes0[] = { ARM::VST2LNq16a, ARM::VST2LNq32a }; 1929 unsigned QOpcodes1[] = { ARM::VST2LNq16b, ARM::VST2LNq32b }; 1930 return SelectVLDSTLane(N, false, 2, DOpcodes, QOpcodes0, QOpcodes1); 1931 } 1932 1933 case Intrinsic::arm_neon_vst3lane: { 1934 unsigned DOpcodes[] = { ARM::VST3LNd8, ARM::VST3LNd16, ARM::VST3LNd32 }; 1935 unsigned QOpcodes0[] = { ARM::VST3LNq16a, ARM::VST3LNq32a }; 1936 unsigned QOpcodes1[] = { ARM::VST3LNq16b, ARM::VST3LNq32b }; 1937 return SelectVLDSTLane(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); 1938 } 1939 1940 case Intrinsic::arm_neon_vst4lane: { 1941 unsigned DOpcodes[] = { ARM::VST4LNd8, ARM::VST4LNd16, ARM::VST4LNd32 }; 1942 unsigned QOpcodes0[] = { ARM::VST4LNq16a, ARM::VST4LNq32a }; 1943 unsigned QOpcodes1[] = { ARM::VST4LNq16b, ARM::VST4LNq32b }; 1944 return SelectVLDSTLane(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); 1945 } 1946 } 1947 } 1948 } 1949 1950 return SelectCode(N); 1951} 1952 1953bool ARMDAGToDAGISel:: 1954SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 1955 std::vector<SDValue> &OutOps) { 1956 assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); 1957 // Require the address to be in a register. That is safe for all ARM 1958 // variants and it is hard to do anything much smarter without knowing 1959 // how the operand is used. 1960 OutOps.push_back(Op); 1961 return false; 1962} 1963 1964/// createARMISelDag - This pass converts a legalized DAG into a 1965/// ARM-specific DAG, ready for instruction scheduling. 1966/// 1967FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM, 1968 CodeGenOpt::Level OptLevel) { 1969 return new ARMDAGToDAGISel(TM, OptLevel); 1970} 1971