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