ARMISelDAGToDAG.cpp revision 01ba461af7eafc9d181a5c349487691f2e801438
1//===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an instruction selector for the ARM target. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "arm-isel" 15#include "ARM.h" 16#include "ARMAddressingModes.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/CommandLine.h" 32#include "llvm/Support/Compiler.h" 33#include "llvm/Support/Debug.h" 34#include "llvm/Support/ErrorHandling.h" 35#include "llvm/Support/raw_ostream.h" 36 37using namespace llvm; 38 39static cl::opt<bool> 40DisableShifterOp("disable-shifter-op", cl::Hidden, 41 cl::desc("Disable isel of shifter-op"), 42 cl::init(false)); 43 44//===--------------------------------------------------------------------===// 45/// ARMDAGToDAGISel - ARM specific code to select ARM machine 46/// instructions for SelectionDAG operations. 47/// 48namespace { 49class ARMDAGToDAGISel : public SelectionDAGISel { 50 ARMBaseTargetMachine &TM; 51 52 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 53 /// make the right decision when generating code for different targets. 54 const ARMSubtarget *Subtarget; 55 56public: 57 explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm, 58 CodeGenOpt::Level OptLevel) 59 : SelectionDAGISel(tm, OptLevel), TM(tm), 60 Subtarget(&TM.getSubtarget<ARMSubtarget>()) { 61 } 62 63 virtual const char *getPassName() const { 64 return "ARM Instruction Selection"; 65 } 66 67 /// getI32Imm - Return a target constant of type i32 with the specified 68 /// value. 69 inline SDValue getI32Imm(unsigned Imm) { 70 return CurDAG->getTargetConstant(Imm, MVT::i32); 71 } 72 73 SDNode *Select(SDNode *N); 74 75 bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A, 76 SDValue &B, SDValue &C); 77 bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base, 78 SDValue &Offset, SDValue &Opc); 79 bool SelectAddrMode2Offset(SDNode *Op, SDValue N, 80 SDValue &Offset, SDValue &Opc); 81 bool SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base, 82 SDValue &Offset, SDValue &Opc); 83 bool SelectAddrMode3Offset(SDNode *Op, SDValue N, 84 SDValue &Offset, SDValue &Opc); 85 bool SelectAddrMode4(SDNode *Op, SDValue N, SDValue &Addr, 86 SDValue &Mode); 87 bool SelectAddrMode5(SDNode *Op, SDValue N, SDValue &Base, 88 SDValue &Offset); 89 bool SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Align); 90 91 bool SelectAddrModePC(SDNode *Op, SDValue N, SDValue &Offset, 92 SDValue &Label); 93 94 bool SelectThumbAddrModeRR(SDNode *Op, SDValue N, SDValue &Base, 95 SDValue &Offset); 96 bool SelectThumbAddrModeRI5(SDNode *Op, SDValue N, unsigned Scale, 97 SDValue &Base, SDValue &OffImm, 98 SDValue &Offset); 99 bool SelectThumbAddrModeS1(SDNode *Op, SDValue N, SDValue &Base, 100 SDValue &OffImm, SDValue &Offset); 101 bool SelectThumbAddrModeS2(SDNode *Op, SDValue N, SDValue &Base, 102 SDValue &OffImm, SDValue &Offset); 103 bool SelectThumbAddrModeS4(SDNode *Op, SDValue N, SDValue &Base, 104 SDValue &OffImm, SDValue &Offset); 105 bool SelectThumbAddrModeSP(SDNode *Op, SDValue N, SDValue &Base, 106 SDValue &OffImm); 107 108 bool SelectT2ShifterOperandReg(SDNode *Op, SDValue N, 109 SDValue &BaseReg, SDValue &Opc); 110 bool SelectT2AddrModeImm12(SDNode *Op, SDValue N, SDValue &Base, 111 SDValue &OffImm); 112 bool SelectT2AddrModeImm8(SDNode *Op, SDValue N, SDValue &Base, 113 SDValue &OffImm); 114 bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 115 SDValue &OffImm); 116 bool SelectT2AddrModeImm8s4(SDNode *Op, SDValue N, SDValue &Base, 117 SDValue &OffImm); 118 bool SelectT2AddrModeSoReg(SDNode *Op, SDValue N, SDValue &Base, 119 SDValue &OffReg, SDValue &ShImm); 120 121 inline bool Pred_so_imm(SDNode *inN) const { 122 ConstantSDNode *N = cast<ConstantSDNode>(inN); 123 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1; 124 } 125 126 inline bool Pred_t2_so_imm(SDNode *inN) const { 127 ConstantSDNode *N = cast<ConstantSDNode>(inN); 128 return ARM_AM::getT2SOImmVal(N->getZExtValue()) != -1; 129 } 130 131 // Include the pieces autogenerated from the target description. 132#include "ARMGenDAGISel.inc" 133 134private: 135 /// SelectARMIndexedLoad - Indexed (pre/post inc/dec) load matching code for 136 /// ARM. 137 SDNode *SelectARMIndexedLoad(SDNode *N); 138 SDNode *SelectT2IndexedLoad(SDNode *N); 139 140 /// SelectVLD - Select NEON load intrinsics. NumVecs should be 141 /// 1, 2, 3 or 4. The opcode arrays specify the instructions used for 142 /// loads of D registers and even subregs and odd subregs of Q registers. 143 /// For NumVecs <= 2, QOpcodes1 is not used. 144 SDNode *SelectVLD(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, 145 unsigned *QOpcodes0, unsigned *QOpcodes1); 146 147 /// SelectVST - Select NEON store intrinsics. NumVecs should 148 /// be 1, 2, 3 or 4. The opcode arrays specify the instructions used for 149 /// stores of D registers and even subregs and odd subregs of Q registers. 150 /// For NumVecs <= 2, QOpcodes1 is not used. 151 SDNode *SelectVST(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, 152 unsigned *QOpcodes0, unsigned *QOpcodes1); 153 154 /// SelectVLDSTLane - Select NEON load/store lane intrinsics. NumVecs should 155 /// be 2, 3 or 4. The opcode arrays specify the instructions used for 156 /// load/store of D registers and even subregs and odd subregs of Q registers. 157 SDNode *SelectVLDSTLane(SDNode *N, bool IsLoad, unsigned NumVecs, 158 unsigned *DOpcodes, unsigned *QOpcodes0, 159 unsigned *QOpcodes1); 160 161 /// SelectVTBL - Select NEON VTBL and VTBX intrinsics. NumVecs should be 2, 162 /// 3 or 4. These are custom-selected so that a REG_SEQUENCE can be 163 /// generated to force the table registers to be consecutive. 164 SDNode *SelectVTBL(SDNode *N, bool IsExt, unsigned NumVecs, unsigned Opc); 165 166 /// SelectV6T2BitfieldExtractOp - Select SBFX/UBFX instructions for ARM. 167 SDNode *SelectV6T2BitfieldExtractOp(SDNode *N, bool isSigned); 168 169 /// SelectCMOVOp - Select CMOV instructions for ARM. 170 SDNode *SelectCMOVOp(SDNode *N); 171 SDNode *SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 172 ARMCC::CondCodes CCVal, SDValue CCR, 173 SDValue InFlag); 174 SDNode *SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 175 ARMCC::CondCodes CCVal, SDValue CCR, 176 SDValue InFlag); 177 SDNode *SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 178 ARMCC::CondCodes CCVal, SDValue CCR, 179 SDValue InFlag); 180 SDNode *SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 181 ARMCC::CondCodes CCVal, SDValue CCR, 182 SDValue InFlag); 183 184 SDNode *SelectConcatVector(SDNode *N); 185 186 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 187 /// inline asm expressions. 188 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 189 char ConstraintCode, 190 std::vector<SDValue> &OutOps); 191 192 // Form pairs of consecutive S, D, or Q registers. 193 SDNode *PairSRegs(EVT VT, SDValue V0, SDValue V1); 194 SDNode *PairDRegs(EVT VT, SDValue V0, SDValue V1); 195 SDNode *PairQRegs(EVT VT, SDValue V0, SDValue V1); 196 197 // Form sequences of 4 consecutive S, D, or Q registers. 198 SDNode *QuadSRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3); 199 SDNode *QuadDRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3); 200 SDNode *QuadQRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3); 201 202 // Form sequences of 8 consecutive D registers. 203 SDNode *OctoDRegs(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3, 204 SDValue V4, SDValue V5, SDValue V6, SDValue V7); 205}; 206} 207 208/// isInt32Immediate - This method tests to see if the node is a 32-bit constant 209/// operand. If so Imm will receive the 32-bit value. 210static bool isInt32Immediate(SDNode *N, unsigned &Imm) { 211 if (N->getOpcode() == ISD::Constant && N->getValueType(0) == MVT::i32) { 212 Imm = cast<ConstantSDNode>(N)->getZExtValue(); 213 return true; 214 } 215 return false; 216} 217 218// isInt32Immediate - This method tests to see if a constant operand. 219// If so Imm will receive the 32 bit value. 220static bool isInt32Immediate(SDValue N, unsigned &Imm) { 221 return isInt32Immediate(N.getNode(), Imm); 222} 223 224// isOpcWithIntImmediate - This method tests to see if the node is a specific 225// opcode and that it has a immediate integer right operand. 226// If so Imm will receive the 32 bit value. 227static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) { 228 return N->getOpcode() == Opc && 229 isInt32Immediate(N->getOperand(1).getNode(), Imm); 230} 231 232 233bool ARMDAGToDAGISel::SelectShifterOperandReg(SDNode *Op, 234 SDValue N, 235 SDValue &BaseReg, 236 SDValue &ShReg, 237 SDValue &Opc) { 238 if (DisableShifterOp) 239 return false; 240 241 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 242 243 // Don't match base register only case. That is matched to a separate 244 // lower complexity pattern with explicit register operand. 245 if (ShOpcVal == ARM_AM::no_shift) return false; 246 247 BaseReg = N.getOperand(0); 248 unsigned ShImmVal = 0; 249 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 250 ShReg = CurDAG->getRegister(0, MVT::i32); 251 ShImmVal = RHS->getZExtValue() & 31; 252 } else { 253 ShReg = N.getOperand(1); 254 } 255 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 256 MVT::i32); 257 return true; 258} 259 260bool ARMDAGToDAGISel::SelectAddrMode2(SDNode *Op, SDValue N, 261 SDValue &Base, SDValue &Offset, 262 SDValue &Opc) { 263 if (N.getOpcode() == ISD::MUL) { 264 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 265 // X * [3,5,9] -> X + X * [2,4,8] etc. 266 int RHSC = (int)RHS->getZExtValue(); 267 if (RHSC & 1) { 268 RHSC = RHSC & ~1; 269 ARM_AM::AddrOpc AddSub = ARM_AM::add; 270 if (RHSC < 0) { 271 AddSub = ARM_AM::sub; 272 RHSC = - RHSC; 273 } 274 if (isPowerOf2_32(RHSC)) { 275 unsigned ShAmt = Log2_32(RHSC); 276 Base = Offset = N.getOperand(0); 277 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, 278 ARM_AM::lsl), 279 MVT::i32); 280 return true; 281 } 282 } 283 } 284 } 285 286 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 287 Base = N; 288 if (N.getOpcode() == ISD::FrameIndex) { 289 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 290 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 291 } else if (N.getOpcode() == ARMISD::Wrapper && 292 !(Subtarget->useMovt() && 293 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 294 Base = N.getOperand(0); 295 } 296 Offset = CurDAG->getRegister(0, MVT::i32); 297 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, 298 ARM_AM::no_shift), 299 MVT::i32); 300 return true; 301 } 302 303 // Match simple R +/- imm12 operands. 304 if (N.getOpcode() == ISD::ADD) 305 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 306 int RHSC = (int)RHS->getZExtValue(); 307 if ((RHSC >= 0 && RHSC < 0x1000) || 308 (RHSC < 0 && RHSC > -0x1000)) { // 12 bits. 309 Base = N.getOperand(0); 310 if (Base.getOpcode() == ISD::FrameIndex) { 311 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 312 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 313 } 314 Offset = CurDAG->getRegister(0, MVT::i32); 315 316 ARM_AM::AddrOpc AddSub = ARM_AM::add; 317 if (RHSC < 0) { 318 AddSub = ARM_AM::sub; 319 RHSC = - RHSC; 320 } 321 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC, 322 ARM_AM::no_shift), 323 MVT::i32); 324 return true; 325 } 326 } 327 328 // Otherwise this is R +/- [possibly shifted] R. 329 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub; 330 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1)); 331 unsigned ShAmt = 0; 332 333 Base = N.getOperand(0); 334 Offset = N.getOperand(1); 335 336 if (ShOpcVal != ARM_AM::no_shift) { 337 // Check to see if the RHS of the shift is a constant, if not, we can't fold 338 // it. 339 if (ConstantSDNode *Sh = 340 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) { 341 ShAmt = Sh->getZExtValue(); 342 Offset = N.getOperand(1).getOperand(0); 343 } else { 344 ShOpcVal = ARM_AM::no_shift; 345 } 346 } 347 348 // Try matching (R shl C) + (R). 349 if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) { 350 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0)); 351 if (ShOpcVal != ARM_AM::no_shift) { 352 // Check to see if the RHS of the shift is a constant, if not, we can't 353 // fold it. 354 if (ConstantSDNode *Sh = 355 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) { 356 ShAmt = Sh->getZExtValue(); 357 Offset = N.getOperand(0).getOperand(0); 358 Base = N.getOperand(1); 359 } else { 360 ShOpcVal = ARM_AM::no_shift; 361 } 362 } 363 } 364 365 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 366 MVT::i32); 367 return true; 368} 369 370bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N, 371 SDValue &Offset, SDValue &Opc) { 372 unsigned Opcode = Op->getOpcode(); 373 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 374 ? cast<LoadSDNode>(Op)->getAddressingMode() 375 : cast<StoreSDNode>(Op)->getAddressingMode(); 376 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 377 ? ARM_AM::add : ARM_AM::sub; 378 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 379 int Val = (int)C->getZExtValue(); 380 if (Val >= 0 && Val < 0x1000) { // 12 bits. 381 Offset = CurDAG->getRegister(0, MVT::i32); 382 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, 383 ARM_AM::no_shift), 384 MVT::i32); 385 return true; 386 } 387 } 388 389 Offset = N; 390 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 391 unsigned ShAmt = 0; 392 if (ShOpcVal != ARM_AM::no_shift) { 393 // Check to see if the RHS of the shift is a constant, if not, we can't fold 394 // it. 395 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 396 ShAmt = Sh->getZExtValue(); 397 Offset = N.getOperand(0); 398 } else { 399 ShOpcVal = ARM_AM::no_shift; 400 } 401 } 402 403 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 404 MVT::i32); 405 return true; 406} 407 408 409bool ARMDAGToDAGISel::SelectAddrMode3(SDNode *Op, SDValue N, 410 SDValue &Base, SDValue &Offset, 411 SDValue &Opc) { 412 if (N.getOpcode() == ISD::SUB) { 413 // X - C is canonicalize to X + -C, no need to handle it here. 414 Base = N.getOperand(0); 415 Offset = N.getOperand(1); 416 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32); 417 return true; 418 } 419 420 if (N.getOpcode() != ISD::ADD) { 421 Base = N; 422 if (N.getOpcode() == ISD::FrameIndex) { 423 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 424 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 425 } 426 Offset = CurDAG->getRegister(0, MVT::i32); 427 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32); 428 return true; 429 } 430 431 // If the RHS is +/- imm8, fold into addr mode. 432 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 433 int RHSC = (int)RHS->getZExtValue(); 434 if ((RHSC >= 0 && RHSC < 256) || 435 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 436 Base = N.getOperand(0); 437 if (Base.getOpcode() == ISD::FrameIndex) { 438 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 439 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 440 } 441 Offset = CurDAG->getRegister(0, MVT::i32); 442 443 ARM_AM::AddrOpc AddSub = ARM_AM::add; 444 if (RHSC < 0) { 445 AddSub = ARM_AM::sub; 446 RHSC = - RHSC; 447 } 448 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32); 449 return true; 450 } 451 } 452 453 Base = N.getOperand(0); 454 Offset = N.getOperand(1); 455 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32); 456 return true; 457} 458 459bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N, 460 SDValue &Offset, SDValue &Opc) { 461 unsigned Opcode = Op->getOpcode(); 462 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 463 ? cast<LoadSDNode>(Op)->getAddressingMode() 464 : cast<StoreSDNode>(Op)->getAddressingMode(); 465 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 466 ? ARM_AM::add : ARM_AM::sub; 467 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 468 int Val = (int)C->getZExtValue(); 469 if (Val >= 0 && Val < 256) { 470 Offset = CurDAG->getRegister(0, MVT::i32); 471 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32); 472 return true; 473 } 474 } 475 476 Offset = N; 477 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32); 478 return true; 479} 480 481bool ARMDAGToDAGISel::SelectAddrMode4(SDNode *Op, SDValue N, 482 SDValue &Addr, SDValue &Mode) { 483 Addr = N; 484 Mode = CurDAG->getTargetConstant(0, MVT::i32); 485 return true; 486} 487 488bool ARMDAGToDAGISel::SelectAddrMode5(SDNode *Op, SDValue N, 489 SDValue &Base, SDValue &Offset) { 490 if (N.getOpcode() != ISD::ADD) { 491 Base = N; 492 if (N.getOpcode() == ISD::FrameIndex) { 493 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 494 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 495 } else if (N.getOpcode() == ARMISD::Wrapper && 496 !(Subtarget->useMovt() && 497 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 498 Base = N.getOperand(0); 499 } 500 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 501 MVT::i32); 502 return true; 503 } 504 505 // If the RHS is +/- imm8, fold into addr mode. 506 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 507 int RHSC = (int)RHS->getZExtValue(); 508 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied by 4. 509 RHSC >>= 2; 510 if ((RHSC >= 0 && RHSC < 256) || 511 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 512 Base = N.getOperand(0); 513 if (Base.getOpcode() == ISD::FrameIndex) { 514 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 515 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 516 } 517 518 ARM_AM::AddrOpc AddSub = ARM_AM::add; 519 if (RHSC < 0) { 520 AddSub = ARM_AM::sub; 521 RHSC = - RHSC; 522 } 523 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC), 524 MVT::i32); 525 return true; 526 } 527 } 528 } 529 530 Base = N; 531 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 532 MVT::i32); 533 return true; 534} 535 536bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Op, SDValue N, 537 SDValue &Addr, SDValue &Align) { 538 Addr = N; 539 // Default to no alignment. 540 Align = CurDAG->getTargetConstant(0, MVT::i32); 541 return true; 542} 543 544bool ARMDAGToDAGISel::SelectAddrModePC(SDNode *Op, SDValue N, 545 SDValue &Offset, SDValue &Label) { 546 if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { 547 Offset = N.getOperand(0); 548 SDValue N1 = N.getOperand(1); 549 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(), 550 MVT::i32); 551 return true; 552 } 553 return false; 554} 555 556bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDNode *Op, SDValue N, 557 SDValue &Base, SDValue &Offset){ 558 // FIXME dl should come from the parent load or store, not the address 559 if (N.getOpcode() != ISD::ADD) { 560 ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N); 561 if (!NC || !NC->isNullValue()) 562 return false; 563 564 Base = Offset = N; 565 return true; 566 } 567 568 Base = N.getOperand(0); 569 Offset = N.getOperand(1); 570 return true; 571} 572 573bool 574ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDNode *Op, SDValue N, 575 unsigned Scale, SDValue &Base, 576 SDValue &OffImm, SDValue &Offset) { 577 if (Scale == 4) { 578 SDValue TmpBase, TmpOffImm; 579 if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm)) 580 return false; // We want to select tLDRspi / tSTRspi instead. 581 if (N.getOpcode() == ARMISD::Wrapper && 582 N.getOperand(0).getOpcode() == ISD::TargetConstantPool) 583 return false; // We want to select tLDRpci instead. 584 } 585 586 if (N.getOpcode() != ISD::ADD) { 587 if (N.getOpcode() == ARMISD::Wrapper && 588 !(Subtarget->useMovt() && 589 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 590 Base = N.getOperand(0); 591 } else 592 Base = N; 593 594 Offset = CurDAG->getRegister(0, MVT::i32); 595 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 596 return true; 597 } 598 599 // Thumb does not have [sp, r] address mode. 600 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 601 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1)); 602 if ((LHSR && LHSR->getReg() == ARM::SP) || 603 (RHSR && RHSR->getReg() == ARM::SP)) { 604 Base = N; 605 Offset = CurDAG->getRegister(0, MVT::i32); 606 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 607 return true; 608 } 609 610 // If the RHS is + imm5 * scale, fold into addr mode. 611 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 612 int RHSC = (int)RHS->getZExtValue(); 613 if ((RHSC & (Scale-1)) == 0) { // The constant is implicitly multiplied. 614 RHSC /= Scale; 615 if (RHSC >= 0 && RHSC < 32) { 616 Base = N.getOperand(0); 617 Offset = CurDAG->getRegister(0, MVT::i32); 618 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 619 return true; 620 } 621 } 622 } 623 624 Base = N.getOperand(0); 625 Offset = N.getOperand(1); 626 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 627 return true; 628} 629 630bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDNode *Op, SDValue N, 631 SDValue &Base, SDValue &OffImm, 632 SDValue &Offset) { 633 return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset); 634} 635 636bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDNode *Op, SDValue N, 637 SDValue &Base, SDValue &OffImm, 638 SDValue &Offset) { 639 return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset); 640} 641 642bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDNode *Op, SDValue N, 643 SDValue &Base, SDValue &OffImm, 644 SDValue &Offset) { 645 return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset); 646} 647 648bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDNode *Op, SDValue N, 649 SDValue &Base, SDValue &OffImm) { 650 if (N.getOpcode() == ISD::FrameIndex) { 651 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 652 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 653 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 654 return true; 655 } 656 657 if (N.getOpcode() != ISD::ADD) 658 return false; 659 660 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 661 if (N.getOperand(0).getOpcode() == ISD::FrameIndex || 662 (LHSR && LHSR->getReg() == ARM::SP)) { 663 // If the RHS is + imm8 * scale, fold into addr mode. 664 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 665 int RHSC = (int)RHS->getZExtValue(); 666 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied. 667 RHSC >>= 2; 668 if (RHSC >= 0 && RHSC < 256) { 669 Base = N.getOperand(0); 670 if (Base.getOpcode() == ISD::FrameIndex) { 671 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 672 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 673 } 674 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 675 return true; 676 } 677 } 678 } 679 } 680 681 return false; 682} 683 684bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDNode *Op, SDValue N, 685 SDValue &BaseReg, 686 SDValue &Opc) { 687 if (DisableShifterOp) 688 return false; 689 690 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 691 692 // Don't match base register only case. That is matched to a separate 693 // lower complexity pattern with explicit register operand. 694 if (ShOpcVal == ARM_AM::no_shift) return false; 695 696 BaseReg = N.getOperand(0); 697 unsigned ShImmVal = 0; 698 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 699 ShImmVal = RHS->getZExtValue() & 31; 700 Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal)); 701 return true; 702 } 703 704 return false; 705} 706 707bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDNode *Op, SDValue N, 708 SDValue &Base, SDValue &OffImm) { 709 // Match simple R + imm12 operands. 710 711 // Base only. 712 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 713 if (N.getOpcode() == ISD::FrameIndex) { 714 // Match frame index... 715 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 716 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 717 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 718 return true; 719 } else if (N.getOpcode() == ARMISD::Wrapper && 720 !(Subtarget->useMovt() && 721 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 722 Base = N.getOperand(0); 723 if (Base.getOpcode() == ISD::TargetConstantPool) 724 return false; // We want to select t2LDRpci instead. 725 } else 726 Base = N; 727 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 728 return true; 729 } 730 731 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 732 if (SelectT2AddrModeImm8(Op, N, Base, OffImm)) 733 // Let t2LDRi8 handle (R - imm8). 734 return false; 735 736 int RHSC = (int)RHS->getZExtValue(); 737 if (N.getOpcode() == ISD::SUB) 738 RHSC = -RHSC; 739 740 if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits (unsigned) 741 Base = N.getOperand(0); 742 if (Base.getOpcode() == ISD::FrameIndex) { 743 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 744 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 745 } 746 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 747 return true; 748 } 749 } 750 751 // Base only. 752 Base = N; 753 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 754 return true; 755} 756 757bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDNode *Op, SDValue N, 758 SDValue &Base, SDValue &OffImm) { 759 // Match simple R - imm8 operands. 760 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::SUB) { 761 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 762 int RHSC = (int)RHS->getSExtValue(); 763 if (N.getOpcode() == ISD::SUB) 764 RHSC = -RHSC; 765 766 if ((RHSC >= -255) && (RHSC < 0)) { // 8 bits (always negative) 767 Base = N.getOperand(0); 768 if (Base.getOpcode() == ISD::FrameIndex) { 769 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 770 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 771 } 772 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 773 return true; 774 } 775 } 776 } 777 778 return false; 779} 780 781bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 782 SDValue &OffImm){ 783 unsigned Opcode = Op->getOpcode(); 784 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 785 ? cast<LoadSDNode>(Op)->getAddressingMode() 786 : cast<StoreSDNode>(Op)->getAddressingMode(); 787 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N)) { 788 int RHSC = (int)RHS->getZExtValue(); 789 if (RHSC >= 0 && RHSC < 0x100) { // 8 bits. 790 OffImm = ((AM == ISD::PRE_INC) || (AM == ISD::POST_INC)) 791 ? CurDAG->getTargetConstant(RHSC, MVT::i32) 792 : CurDAG->getTargetConstant(-RHSC, MVT::i32); 793 return true; 794 } 795 } 796 797 return false; 798} 799 800bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDNode *Op, SDValue N, 801 SDValue &Base, SDValue &OffImm) { 802 if (N.getOpcode() == ISD::ADD) { 803 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 804 int RHSC = (int)RHS->getZExtValue(); 805 // 8 bits. 806 if (((RHSC & 0x3) == 0) && 807 ((RHSC >= 0 && RHSC < 0x400) || (RHSC < 0 && RHSC > -0x400))) { 808 Base = N.getOperand(0); 809 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 810 return true; 811 } 812 } 813 } else if (N.getOpcode() == ISD::SUB) { 814 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 815 int RHSC = (int)RHS->getZExtValue(); 816 // 8 bits. 817 if (((RHSC & 0x3) == 0) && (RHSC >= 0 && RHSC < 0x400)) { 818 Base = N.getOperand(0); 819 OffImm = CurDAG->getTargetConstant(-RHSC, MVT::i32); 820 return true; 821 } 822 } 823 } 824 825 return false; 826} 827 828bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDNode *Op, SDValue N, 829 SDValue &Base, 830 SDValue &OffReg, SDValue &ShImm) { 831 // (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12. 832 if (N.getOpcode() != ISD::ADD) 833 return false; 834 835 // Leave (R + imm12) for t2LDRi12, (R - imm8) for t2LDRi8. 836 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 837 int RHSC = (int)RHS->getZExtValue(); 838 if (RHSC >= 0 && RHSC < 0x1000) // 12 bits (unsigned) 839 return false; 840 else if (RHSC < 0 && RHSC >= -255) // 8 bits 841 return false; 842 } 843 844 // Look for (R + R) or (R + (R << [1,2,3])). 845 unsigned ShAmt = 0; 846 Base = N.getOperand(0); 847 OffReg = N.getOperand(1); 848 849 // Swap if it is ((R << c) + R). 850 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg); 851 if (ShOpcVal != ARM_AM::lsl) { 852 ShOpcVal = ARM_AM::getShiftOpcForNode(Base); 853 if (ShOpcVal == ARM_AM::lsl) 854 std::swap(Base, OffReg); 855 } 856 857 if (ShOpcVal == ARM_AM::lsl) { 858 // Check to see if the RHS of the shift is a constant, if not, we can't fold 859 // it. 860 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(OffReg.getOperand(1))) { 861 ShAmt = Sh->getZExtValue(); 862 if (ShAmt >= 4) { 863 ShAmt = 0; 864 ShOpcVal = ARM_AM::no_shift; 865 } else 866 OffReg = OffReg.getOperand(0); 867 } else { 868 ShOpcVal = ARM_AM::no_shift; 869 } 870 } 871 872 ShImm = CurDAG->getTargetConstant(ShAmt, MVT::i32); 873 874 return true; 875} 876 877//===--------------------------------------------------------------------===// 878 879/// getAL - Returns a ARMCC::AL immediate node. 880static inline SDValue getAL(SelectionDAG *CurDAG) { 881 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32); 882} 883 884SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDNode *N) { 885 LoadSDNode *LD = cast<LoadSDNode>(N); 886 ISD::MemIndexedMode AM = LD->getAddressingMode(); 887 if (AM == ISD::UNINDEXED) 888 return NULL; 889 890 EVT LoadedVT = LD->getMemoryVT(); 891 SDValue Offset, AMOpc; 892 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 893 unsigned Opcode = 0; 894 bool Match = false; 895 if (LoadedVT == MVT::i32 && 896 SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { 897 Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST; 898 Match = true; 899 } else if (LoadedVT == MVT::i16 && 900 SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 901 Match = true; 902 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) 903 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) 904 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); 905 } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) { 906 if (LD->getExtensionType() == ISD::SEXTLOAD) { 907 if (SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 908 Match = true; 909 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; 910 } 911 } else { 912 if (SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { 913 Match = true; 914 Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST; 915 } 916 } 917 } 918 919 if (Match) { 920 SDValue Chain = LD->getChain(); 921 SDValue Base = LD->getBasePtr(); 922 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), 923 CurDAG->getRegister(0, MVT::i32), Chain }; 924 return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32, 925 MVT::Other, Ops, 6); 926 } 927 928 return NULL; 929} 930 931SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) { 932 LoadSDNode *LD = cast<LoadSDNode>(N); 933 ISD::MemIndexedMode AM = LD->getAddressingMode(); 934 if (AM == ISD::UNINDEXED) 935 return NULL; 936 937 EVT LoadedVT = LD->getMemoryVT(); 938 bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD; 939 SDValue Offset; 940 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 941 unsigned Opcode = 0; 942 bool Match = false; 943 if (SelectT2AddrModeImm8Offset(N, LD->getOffset(), Offset)) { 944 switch (LoadedVT.getSimpleVT().SimpleTy) { 945 case MVT::i32: 946 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST; 947 break; 948 case MVT::i16: 949 if (isSExtLd) 950 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST; 951 else 952 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST; 953 break; 954 case MVT::i8: 955 case MVT::i1: 956 if (isSExtLd) 957 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST; 958 else 959 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST; 960 break; 961 default: 962 return NULL; 963 } 964 Match = true; 965 } 966 967 if (Match) { 968 SDValue Chain = LD->getChain(); 969 SDValue Base = LD->getBasePtr(); 970 SDValue Ops[]= { Base, Offset, getAL(CurDAG), 971 CurDAG->getRegister(0, MVT::i32), Chain }; 972 return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32, 973 MVT::Other, Ops, 5); 974 } 975 976 return NULL; 977} 978 979/// PairSRegs - Form a D register from a pair of S registers. 980/// 981SDNode *ARMDAGToDAGISel::PairSRegs(EVT VT, SDValue V0, SDValue V1) { 982 DebugLoc dl = V0.getNode()->getDebugLoc(); 983 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32); 984 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32); 985 const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 }; 986 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4); 987} 988 989/// PairDRegs - Form a quad register from a pair of D registers. 990/// 991SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) { 992 DebugLoc dl = V0.getNode()->getDebugLoc(); 993 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32); 994 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32); 995 const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 }; 996 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4); 997} 998 999/// PairQRegs - Form 4 consecutive D registers from a pair of Q registers. 1000/// 1001SDNode *ARMDAGToDAGISel::PairQRegs(EVT VT, SDValue V0, SDValue V1) { 1002 DebugLoc dl = V0.getNode()->getDebugLoc(); 1003 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32); 1004 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32); 1005 const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 }; 1006 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4); 1007} 1008 1009/// QuadSRegs - Form 4 consecutive S registers. 1010/// 1011SDNode *ARMDAGToDAGISel::QuadSRegs(EVT VT, SDValue V0, SDValue V1, 1012 SDValue V2, SDValue V3) { 1013 DebugLoc dl = V0.getNode()->getDebugLoc(); 1014 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32); 1015 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32); 1016 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, MVT::i32); 1017 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, MVT::i32); 1018 const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 }; 1019 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8); 1020} 1021 1022/// QuadDRegs - Form 4 consecutive D registers. 1023/// 1024SDNode *ARMDAGToDAGISel::QuadDRegs(EVT VT, SDValue V0, SDValue V1, 1025 SDValue V2, SDValue V3) { 1026 DebugLoc dl = V0.getNode()->getDebugLoc(); 1027 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32); 1028 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32); 1029 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, MVT::i32); 1030 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, MVT::i32); 1031 const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 }; 1032 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8); 1033} 1034 1035/// QuadQRegs - Form 4 consecutive Q registers. 1036/// 1037SDNode *ARMDAGToDAGISel::QuadQRegs(EVT VT, SDValue V0, SDValue V1, 1038 SDValue V2, SDValue V3) { 1039 DebugLoc dl = V0.getNode()->getDebugLoc(); 1040 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32); 1041 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32); 1042 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, MVT::i32); 1043 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, MVT::i32); 1044 const SDValue Ops[] = { V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3 }; 1045 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 8); 1046} 1047 1048/// OctoDRegs - Form 8 consecutive D registers. 1049/// 1050SDNode *ARMDAGToDAGISel::OctoDRegs(EVT VT, SDValue V0, SDValue V1, 1051 SDValue V2, SDValue V3, 1052 SDValue V4, SDValue V5, 1053 SDValue V6, SDValue V7) { 1054 DebugLoc dl = V0.getNode()->getDebugLoc(); 1055 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32); 1056 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32); 1057 SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, MVT::i32); 1058 SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, MVT::i32); 1059 SDValue SubReg4 = CurDAG->getTargetConstant(ARM::dsub_4, MVT::i32); 1060 SDValue SubReg5 = CurDAG->getTargetConstant(ARM::dsub_5, MVT::i32); 1061 SDValue SubReg6 = CurDAG->getTargetConstant(ARM::dsub_6, MVT::i32); 1062 SDValue SubReg7 = CurDAG->getTargetConstant(ARM::dsub_7, MVT::i32); 1063 const SDValue Ops[] ={ V0, SubReg0, V1, SubReg1, V2, SubReg2, V3, SubReg3, 1064 V4, SubReg4, V5, SubReg5, V6, SubReg6, V7, SubReg7 }; 1065 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 16); 1066} 1067 1068/// GetNEONSubregVT - Given a type for a 128-bit NEON vector, return the type 1069/// for a 64-bit subregister of the vector. 1070static EVT GetNEONSubregVT(EVT VT) { 1071 switch (VT.getSimpleVT().SimpleTy) { 1072 default: llvm_unreachable("unhandled NEON type"); 1073 case MVT::v16i8: return MVT::v8i8; 1074 case MVT::v8i16: return MVT::v4i16; 1075 case MVT::v4f32: return MVT::v2f32; 1076 case MVT::v4i32: return MVT::v2i32; 1077 case MVT::v2i64: return MVT::v1i64; 1078 } 1079} 1080 1081SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs, 1082 unsigned *DOpcodes, unsigned *QOpcodes0, 1083 unsigned *QOpcodes1) { 1084 assert(NumVecs >= 1 && NumVecs <= 4 && "VLD NumVecs out-of-range"); 1085 DebugLoc dl = N->getDebugLoc(); 1086 1087 SDValue MemAddr, Align; 1088 if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align)) 1089 return NULL; 1090 1091 SDValue Chain = N->getOperand(0); 1092 EVT VT = N->getValueType(0); 1093 bool is64BitVector = VT.is64BitVector(); 1094 1095 unsigned OpcodeIndex; 1096 switch (VT.getSimpleVT().SimpleTy) { 1097 default: llvm_unreachable("unhandled vld type"); 1098 // Double-register operations: 1099 case MVT::v8i8: OpcodeIndex = 0; break; 1100 case MVT::v4i16: OpcodeIndex = 1; break; 1101 case MVT::v2f32: 1102 case MVT::v2i32: OpcodeIndex = 2; break; 1103 case MVT::v1i64: OpcodeIndex = 3; break; 1104 // Quad-register operations: 1105 case MVT::v16i8: OpcodeIndex = 0; break; 1106 case MVT::v8i16: OpcodeIndex = 1; break; 1107 case MVT::v4f32: 1108 case MVT::v4i32: OpcodeIndex = 2; break; 1109 case MVT::v2i64: OpcodeIndex = 3; 1110 assert(NumVecs == 1 && "v2i64 type only supported for VLD1"); 1111 break; 1112 } 1113 1114 SDValue Pred = getAL(CurDAG); 1115 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1116 if (is64BitVector) { 1117 unsigned Opc = DOpcodes[OpcodeIndex]; 1118 const SDValue Ops[] = { MemAddr, Align, Pred, Reg0, Chain }; 1119 std::vector<EVT> ResTys(NumVecs, VT); 1120 ResTys.push_back(MVT::Other); 1121 SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); 1122 if (NumVecs < 2) 1123 return VLd; 1124 1125 SDValue RegSeq; 1126 SDValue V0 = SDValue(VLd, 0); 1127 SDValue V1 = SDValue(VLd, 1); 1128 1129 // Form a REG_SEQUENCE to force register allocation. 1130 if (NumVecs == 2) 1131 RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0); 1132 else { 1133 SDValue V2 = SDValue(VLd, 2); 1134 // If it's a vld3, form a quad D-register but discard the last part. 1135 SDValue V3 = (NumVecs == 3) 1136 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0) 1137 : SDValue(VLd, 3); 1138 RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0); 1139 } 1140 1141 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 1142 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1143 SDValue D = CurDAG->getTargetExtractSubreg(ARM::dsub_0+Vec, 1144 dl, VT, RegSeq); 1145 ReplaceUses(SDValue(N, Vec), D); 1146 } 1147 ReplaceUses(SDValue(N, NumVecs), SDValue(VLd, NumVecs)); 1148 return NULL; 1149 } 1150 1151 EVT RegVT = GetNEONSubregVT(VT); 1152 if (NumVecs <= 2) { 1153 // Quad registers are directly supported for VLD1 and VLD2, 1154 // loading pairs of D regs. 1155 unsigned Opc = QOpcodes0[OpcodeIndex]; 1156 const SDValue Ops[] = { MemAddr, Align, Pred, Reg0, Chain }; 1157 std::vector<EVT> ResTys(2 * NumVecs, RegVT); 1158 ResTys.push_back(MVT::Other); 1159 SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); 1160 Chain = SDValue(VLd, 2 * NumVecs); 1161 1162 // Combine the even and odd subregs to produce the result. 1163 if (NumVecs == 1) { 1164 SDNode *Q = PairDRegs(VT, SDValue(VLd, 0), SDValue(VLd, 1)); 1165 ReplaceUses(SDValue(N, 0), SDValue(Q, 0)); 1166 } else { 1167 SDValue QQ = SDValue(QuadDRegs(MVT::v4i64, 1168 SDValue(VLd, 0), SDValue(VLd, 1), 1169 SDValue(VLd, 2), SDValue(VLd, 3)), 0); 1170 SDValue Q0 = CurDAG->getTargetExtractSubreg(ARM::qsub_0, dl, VT, QQ); 1171 SDValue Q1 = CurDAG->getTargetExtractSubreg(ARM::qsub_1, dl, VT, QQ); 1172 ReplaceUses(SDValue(N, 0), Q0); 1173 ReplaceUses(SDValue(N, 1), Q1); 1174 } 1175 } else { 1176 // Otherwise, quad registers are loaded with two separate instructions, 1177 // where one loads the even registers and the other loads the odd registers. 1178 1179 std::vector<EVT> ResTys(NumVecs, RegVT); 1180 ResTys.push_back(MemAddr.getValueType()); 1181 ResTys.push_back(MVT::Other); 1182 1183 // Load the even subregs. 1184 unsigned Opc = QOpcodes0[OpcodeIndex]; 1185 const SDValue OpsA[] = { MemAddr, Align, Reg0, Pred, Reg0, Chain }; 1186 SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 6); 1187 Chain = SDValue(VLdA, NumVecs+1); 1188 1189 // Load the odd subregs. 1190 Opc = QOpcodes1[OpcodeIndex]; 1191 const SDValue OpsB[] = { SDValue(VLdA, NumVecs), 1192 Align, Reg0, Pred, Reg0, Chain }; 1193 SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 6); 1194 Chain = SDValue(VLdB, NumVecs+1); 1195 1196 SDValue V0 = SDValue(VLdA, 0); 1197 SDValue V1 = SDValue(VLdB, 0); 1198 SDValue V2 = SDValue(VLdA, 1); 1199 SDValue V3 = SDValue(VLdB, 1); 1200 SDValue V4 = SDValue(VLdA, 2); 1201 SDValue V5 = SDValue(VLdB, 2); 1202 SDValue V6 = (NumVecs == 3) 1203 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,RegVT), 0) 1204 : SDValue(VLdA, 3); 1205 SDValue V7 = (NumVecs == 3) 1206 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,RegVT), 0) 1207 : SDValue(VLdB, 3); 1208 SDValue RegSeq = SDValue(OctoDRegs(MVT::v8i64, V0, V1, V2, V3, 1209 V4, V5, V6, V7), 0); 1210 1211 // Extract out the 3 / 4 Q registers. 1212 assert(ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering"); 1213 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1214 SDValue Q = CurDAG->getTargetExtractSubreg(ARM::qsub_0+Vec, 1215 dl, VT, RegSeq); 1216 ReplaceUses(SDValue(N, Vec), Q); 1217 } 1218 } 1219 ReplaceUses(SDValue(N, NumVecs), Chain); 1220 return NULL; 1221} 1222 1223SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs, 1224 unsigned *DOpcodes, unsigned *QOpcodes0, 1225 unsigned *QOpcodes1) { 1226 assert(NumVecs >= 1 && NumVecs <= 4 && "VST NumVecs out-of-range"); 1227 DebugLoc dl = N->getDebugLoc(); 1228 1229 SDValue MemAddr, Align; 1230 if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align)) 1231 return NULL; 1232 1233 SDValue Chain = N->getOperand(0); 1234 EVT VT = N->getOperand(3).getValueType(); 1235 bool is64BitVector = VT.is64BitVector(); 1236 1237 unsigned OpcodeIndex; 1238 switch (VT.getSimpleVT().SimpleTy) { 1239 default: llvm_unreachable("unhandled vst type"); 1240 // Double-register operations: 1241 case MVT::v8i8: OpcodeIndex = 0; break; 1242 case MVT::v4i16: OpcodeIndex = 1; break; 1243 case MVT::v2f32: 1244 case MVT::v2i32: OpcodeIndex = 2; break; 1245 case MVT::v1i64: OpcodeIndex = 3; break; 1246 // Quad-register operations: 1247 case MVT::v16i8: OpcodeIndex = 0; break; 1248 case MVT::v8i16: OpcodeIndex = 1; break; 1249 case MVT::v4f32: 1250 case MVT::v4i32: OpcodeIndex = 2; break; 1251 case MVT::v2i64: OpcodeIndex = 3; 1252 assert(NumVecs == 1 && "v2i64 type only supported for VST1"); 1253 break; 1254 } 1255 1256 SDValue Pred = getAL(CurDAG); 1257 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1258 1259 SmallVector<SDValue, 10> Ops; 1260 Ops.push_back(MemAddr); 1261 Ops.push_back(Align); 1262 1263 // FIXME: This is a temporary flag to distinguish VSTs that have been 1264 // converted to pseudo instructions. 1265 bool usePseudoInstrs = (NumVecs >= 3); 1266 1267 if (is64BitVector) { 1268 if (NumVecs >= 2) { 1269 SDValue RegSeq; 1270 SDValue V0 = N->getOperand(0+3); 1271 SDValue V1 = N->getOperand(1+3); 1272 1273 // Form a REG_SEQUENCE to force register allocation. 1274 if (NumVecs == 2) 1275 RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0); 1276 else { 1277 SDValue V2 = N->getOperand(2+3); 1278 // If it's a vld3, form a quad D-register and leave the last part as 1279 // an undef. 1280 SDValue V3 = (NumVecs == 3) 1281 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0) 1282 : N->getOperand(3+3); 1283 RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0); 1284 } 1285 if (usePseudoInstrs) 1286 Ops.push_back(RegSeq); 1287 else { 1288 1289 // Now extract the D registers back out. 1290 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, VT, 1291 RegSeq)); 1292 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, VT, 1293 RegSeq)); 1294 if (NumVecs > 2) 1295 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_2, dl, VT, 1296 RegSeq)); 1297 if (NumVecs > 3) 1298 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, VT, 1299 RegSeq)); 1300 } 1301 } else { 1302 Ops.push_back(N->getOperand(3)); 1303 } 1304 Ops.push_back(Pred); 1305 Ops.push_back(Reg0); // predicate register 1306 Ops.push_back(Chain); 1307 unsigned Opc = DOpcodes[OpcodeIndex]; 1308 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 1309 usePseudoInstrs ? 6 : NumVecs+5); 1310 } 1311 1312 EVT RegVT = GetNEONSubregVT(VT); 1313 if (NumVecs <= 2) { 1314 // Quad registers are directly supported for VST1 and VST2, 1315 // storing pairs of D regs. 1316 unsigned Opc = QOpcodes0[OpcodeIndex]; 1317 if (NumVecs == 2) { 1318 // First extract the pair of Q registers. 1319 SDValue Q0 = N->getOperand(3); 1320 SDValue Q1 = N->getOperand(4); 1321 1322 // Form a QQ register. 1323 SDValue QQ = SDValue(PairQRegs(MVT::v4i64, Q0, Q1), 0); 1324 1325 // Now extract the D registers back out. 1326 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT, 1327 QQ)); 1328 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT, 1329 QQ)); 1330 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_2, dl, RegVT, 1331 QQ)); 1332 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, RegVT, 1333 QQ)); 1334 Ops.push_back(Pred); 1335 Ops.push_back(Reg0); // predicate register 1336 Ops.push_back(Chain); 1337 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 5 + 4); 1338 } else { 1339 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1340 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT, 1341 N->getOperand(Vec+3))); 1342 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT, 1343 N->getOperand(Vec+3))); 1344 } 1345 Ops.push_back(Pred); 1346 Ops.push_back(Reg0); // predicate register 1347 Ops.push_back(Chain); 1348 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 1349 5 + 2 * NumVecs); 1350 } 1351 } 1352 1353 // Otherwise, quad registers are stored with two separate instructions, 1354 // where one stores the even registers and the other stores the odd registers. 1355 1356 // Form the QQQQ REG_SEQUENCE. 1357 SDValue V[8]; 1358 for (unsigned Vec = 0, i = 0; Vec < NumVecs; ++Vec, i+=2) { 1359 V[i] = CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, RegVT, 1360 N->getOperand(Vec+3)); 1361 V[i+1] = CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, RegVT, 1362 N->getOperand(Vec+3)); 1363 } 1364 if (NumVecs == 3) 1365 V[6] = V[7] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, 1366 dl, RegVT), 0); 1367 1368 SDValue RegSeq = SDValue(OctoDRegs(MVT::v8i64, V[0], V[1], V[2], V[3], 1369 V[4], V[5], V[6], V[7]), 0); 1370 1371 // Store the even D registers. 1372 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 1373 Ops.push_back(Reg0); // post-access address offset 1374 if (usePseudoInstrs) 1375 Ops.push_back(RegSeq); 1376 else 1377 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1378 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0+Vec*2, dl, 1379 RegVT, RegSeq)); 1380 Ops.push_back(Pred); 1381 Ops.push_back(Reg0); // predicate register 1382 Ops.push_back(Chain); 1383 unsigned Opc = QOpcodes0[OpcodeIndex]; 1384 SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(), 1385 MVT::Other, Ops.data(), 1386 usePseudoInstrs ? 7 : NumVecs+6); 1387 Chain = SDValue(VStA, 1); 1388 1389 // Store the odd D registers. 1390 Ops[0] = SDValue(VStA, 0); // MemAddr 1391 if (usePseudoInstrs) 1392 Ops[6] = Chain; 1393 else { 1394 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1395 Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::dsub_1+Vec*2, dl, 1396 RegVT, RegSeq); 1397 Ops[NumVecs+5] = Chain; 1398 } 1399 Opc = QOpcodes1[OpcodeIndex]; 1400 SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(), 1401 MVT::Other, Ops.data(), 1402 usePseudoInstrs ? 7 : NumVecs+6); 1403 Chain = SDValue(VStB, 1); 1404 ReplaceUses(SDValue(N, 0), Chain); 1405 return NULL; 1406} 1407 1408SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad, 1409 unsigned NumVecs, unsigned *DOpcodes, 1410 unsigned *QOpcodes0, 1411 unsigned *QOpcodes1) { 1412 assert(NumVecs >=2 && NumVecs <= 4 && "VLDSTLane NumVecs out-of-range"); 1413 DebugLoc dl = N->getDebugLoc(); 1414 1415 SDValue MemAddr, Align; 1416 if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align)) 1417 return NULL; 1418 1419 SDValue Chain = N->getOperand(0); 1420 unsigned Lane = 1421 cast<ConstantSDNode>(N->getOperand(NumVecs+3))->getZExtValue(); 1422 EVT VT = IsLoad ? N->getValueType(0) : N->getOperand(3).getValueType(); 1423 bool is64BitVector = VT.is64BitVector(); 1424 1425 // Quad registers are handled by load/store of subregs. Find the subreg info. 1426 unsigned NumElts = 0; 1427 bool Even = false; 1428 EVT RegVT = VT; 1429 if (!is64BitVector) { 1430 RegVT = GetNEONSubregVT(VT); 1431 NumElts = RegVT.getVectorNumElements(); 1432 Even = Lane < NumElts; 1433 } 1434 1435 unsigned OpcodeIndex; 1436 switch (VT.getSimpleVT().SimpleTy) { 1437 default: llvm_unreachable("unhandled vld/vst lane type"); 1438 // Double-register operations: 1439 case MVT::v8i8: OpcodeIndex = 0; break; 1440 case MVT::v4i16: OpcodeIndex = 1; break; 1441 case MVT::v2f32: 1442 case MVT::v2i32: OpcodeIndex = 2; break; 1443 // Quad-register operations: 1444 case MVT::v8i16: OpcodeIndex = 0; break; 1445 case MVT::v4f32: 1446 case MVT::v4i32: OpcodeIndex = 1; break; 1447 } 1448 1449 SDValue Pred = getAL(CurDAG); 1450 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1451 1452 SmallVector<SDValue, 10> Ops; 1453 Ops.push_back(MemAddr); 1454 Ops.push_back(Align); 1455 1456 unsigned Opc = 0; 1457 if (is64BitVector) { 1458 Opc = DOpcodes[OpcodeIndex]; 1459 SDValue RegSeq; 1460 SDValue V0 = N->getOperand(0+3); 1461 SDValue V1 = N->getOperand(1+3); 1462 if (NumVecs == 2) { 1463 RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0); 1464 } else { 1465 SDValue V2 = N->getOperand(2+3); 1466 SDValue V3 = (NumVecs == 3) 1467 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0) 1468 : N->getOperand(3+3); 1469 RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0); 1470 } 1471 1472 // Now extract the D registers back out. 1473 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, VT, RegSeq)); 1474 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, VT, RegSeq)); 1475 if (NumVecs > 2) 1476 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_2, dl, VT,RegSeq)); 1477 if (NumVecs > 3) 1478 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, VT,RegSeq)); 1479 } else { 1480 // Check if this is loading the even or odd subreg of a Q register. 1481 if (Lane < NumElts) { 1482 Opc = QOpcodes0[OpcodeIndex]; 1483 } else { 1484 Lane -= NumElts; 1485 Opc = QOpcodes1[OpcodeIndex]; 1486 } 1487 1488 SDValue RegSeq; 1489 SDValue V0 = N->getOperand(0+3); 1490 SDValue V1 = N->getOperand(1+3); 1491 if (NumVecs == 2) { 1492 RegSeq = SDValue(PairQRegs(MVT::v4i64, V0, V1), 0); 1493 } else { 1494 SDValue V2 = N->getOperand(2+3); 1495 SDValue V3 = (NumVecs == 3) 1496 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0) 1497 : N->getOperand(3+3); 1498 RegSeq = SDValue(QuadQRegs(MVT::v8i64, V0, V1, V2, V3), 0); 1499 } 1500 1501 // Extract the subregs of the input vector. 1502 unsigned SubIdx = Even ? ARM::dsub_0 : ARM::dsub_1; 1503 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1504 Ops.push_back(CurDAG->getTargetExtractSubreg(SubIdx+Vec*2, dl, RegVT, 1505 RegSeq)); 1506 } 1507 Ops.push_back(getI32Imm(Lane)); 1508 Ops.push_back(Pred); 1509 Ops.push_back(Reg0); 1510 Ops.push_back(Chain); 1511 1512 if (!IsLoad) 1513 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+6); 1514 1515 std::vector<EVT> ResTys(NumVecs, RegVT); 1516 ResTys.push_back(MVT::Other); 1517 SDNode *VLdLn = CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(),NumVecs+6); 1518 1519 // Form a REG_SEQUENCE to force register allocation. 1520 SDValue RegSeq; 1521 if (is64BitVector) { 1522 SDValue V0 = SDValue(VLdLn, 0); 1523 SDValue V1 = SDValue(VLdLn, 1); 1524 if (NumVecs == 2) { 1525 RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0); 1526 } else { 1527 SDValue V2 = SDValue(VLdLn, 2); 1528 // If it's a vld3, form a quad D-register but discard the last part. 1529 SDValue V3 = (NumVecs == 3) 1530 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0) 1531 : SDValue(VLdLn, 3); 1532 RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0); 1533 } 1534 } else { 1535 // For 128-bit vectors, take the 64-bit results of the load and insert 1536 // them as subregs into the result. 1537 SDValue V[8]; 1538 for (unsigned Vec = 0, i = 0; Vec < NumVecs; ++Vec, i+=2) { 1539 if (Even) { 1540 V[i] = SDValue(VLdLn, Vec); 1541 V[i+1] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, 1542 dl, RegVT), 0); 1543 } else { 1544 V[i] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, 1545 dl, RegVT), 0); 1546 V[i+1] = SDValue(VLdLn, Vec); 1547 } 1548 } 1549 if (NumVecs == 3) 1550 V[6] = V[7] = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, 1551 dl, RegVT), 0); 1552 1553 if (NumVecs == 2) 1554 RegSeq = SDValue(QuadDRegs(MVT::v4i64, V[0], V[1], V[2], V[3]), 0); 1555 else 1556 RegSeq = SDValue(OctoDRegs(MVT::v8i64, V[0], V[1], V[2], V[3], 1557 V[4], V[5], V[6], V[7]), 0); 1558 } 1559 1560 assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering"); 1561 assert(ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering"); 1562 unsigned SubIdx = is64BitVector ? ARM::dsub_0 : ARM::qsub_0; 1563 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1564 ReplaceUses(SDValue(N, Vec), 1565 CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, RegSeq)); 1566 ReplaceUses(SDValue(N, NumVecs), SDValue(VLdLn, NumVecs)); 1567 return NULL; 1568} 1569 1570SDNode *ARMDAGToDAGISel::SelectVTBL(SDNode *N, bool IsExt, unsigned NumVecs, 1571 unsigned Opc) { 1572 assert(NumVecs >= 2 && NumVecs <= 4 && "VTBL NumVecs out-of-range"); 1573 DebugLoc dl = N->getDebugLoc(); 1574 EVT VT = N->getValueType(0); 1575 unsigned FirstTblReg = IsExt ? 2 : 1; 1576 1577 // Form a REG_SEQUENCE to force register allocation. 1578 SDValue RegSeq; 1579 SDValue V0 = N->getOperand(FirstTblReg + 0); 1580 SDValue V1 = N->getOperand(FirstTblReg + 1); 1581 if (NumVecs == 2) 1582 RegSeq = SDValue(PairDRegs(MVT::v16i8, V0, V1), 0); 1583 else { 1584 SDValue V2 = N->getOperand(FirstTblReg + 2); 1585 // If it's a vtbl3, form a quad D-register and leave the last part as 1586 // an undef. 1587 SDValue V3 = (NumVecs == 3) 1588 ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0) 1589 : N->getOperand(FirstTblReg + 3); 1590 RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0); 1591 } 1592 1593 // Now extract the D registers back out. 1594 SmallVector<SDValue, 6> Ops; 1595 if (IsExt) 1596 Ops.push_back(N->getOperand(1)); 1597 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, VT, RegSeq)); 1598 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, VT, RegSeq)); 1599 if (NumVecs > 2) 1600 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_2, dl, VT, RegSeq)); 1601 if (NumVecs > 3) 1602 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, VT, RegSeq)); 1603 1604 Ops.push_back(N->getOperand(FirstTblReg + NumVecs)); 1605 Ops.push_back(getAL(CurDAG)); // predicate 1606 Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // predicate register 1607 return CurDAG->getMachineNode(Opc, dl, VT, Ops.data(), Ops.size()); 1608} 1609 1610SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N, 1611 bool isSigned) { 1612 if (!Subtarget->hasV6T2Ops()) 1613 return NULL; 1614 1615 unsigned Opc = isSigned ? (Subtarget->isThumb() ? ARM::t2SBFX : ARM::SBFX) 1616 : (Subtarget->isThumb() ? ARM::t2UBFX : ARM::UBFX); 1617 1618 1619 // For unsigned extracts, check for a shift right and mask 1620 unsigned And_imm = 0; 1621 if (N->getOpcode() == ISD::AND) { 1622 if (isOpcWithIntImmediate(N, ISD::AND, And_imm)) { 1623 1624 // The immediate is a mask of the low bits iff imm & (imm+1) == 0 1625 if (And_imm & (And_imm + 1)) 1626 return NULL; 1627 1628 unsigned Srl_imm = 0; 1629 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRL, 1630 Srl_imm)) { 1631 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 1632 1633 unsigned Width = CountTrailingOnes_32(And_imm); 1634 unsigned LSB = Srl_imm; 1635 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1636 SDValue Ops[] = { N->getOperand(0).getOperand(0), 1637 CurDAG->getTargetConstant(LSB, MVT::i32), 1638 CurDAG->getTargetConstant(Width, MVT::i32), 1639 getAL(CurDAG), Reg0 }; 1640 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); 1641 } 1642 } 1643 return NULL; 1644 } 1645 1646 // Otherwise, we're looking for a shift of a shift 1647 unsigned Shl_imm = 0; 1648 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, Shl_imm)) { 1649 assert(Shl_imm > 0 && Shl_imm < 32 && "bad amount in shift node!"); 1650 unsigned Srl_imm = 0; 1651 if (isInt32Immediate(N->getOperand(1), Srl_imm)) { 1652 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 1653 unsigned Width = 32 - Srl_imm; 1654 int LSB = Srl_imm - Shl_imm; 1655 if (LSB < 0) 1656 return NULL; 1657 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1658 SDValue Ops[] = { N->getOperand(0).getOperand(0), 1659 CurDAG->getTargetConstant(LSB, MVT::i32), 1660 CurDAG->getTargetConstant(Width, MVT::i32), 1661 getAL(CurDAG), Reg0 }; 1662 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); 1663 } 1664 } 1665 return NULL; 1666} 1667 1668SDNode *ARMDAGToDAGISel:: 1669SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1670 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1671 SDValue CPTmp0; 1672 SDValue CPTmp1; 1673 if (SelectT2ShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1)) { 1674 unsigned SOVal = cast<ConstantSDNode>(CPTmp1)->getZExtValue(); 1675 unsigned SOShOp = ARM_AM::getSORegShOp(SOVal); 1676 unsigned Opc = 0; 1677 switch (SOShOp) { 1678 case ARM_AM::lsl: Opc = ARM::t2MOVCClsl; break; 1679 case ARM_AM::lsr: Opc = ARM::t2MOVCClsr; break; 1680 case ARM_AM::asr: Opc = ARM::t2MOVCCasr; break; 1681 case ARM_AM::ror: Opc = ARM::t2MOVCCror; break; 1682 default: 1683 llvm_unreachable("Unknown so_reg opcode!"); 1684 break; 1685 } 1686 SDValue SOShImm = 1687 CurDAG->getTargetConstant(ARM_AM::getSORegOffset(SOVal), MVT::i32); 1688 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1689 SDValue Ops[] = { FalseVal, CPTmp0, SOShImm, CC, CCR, InFlag }; 1690 return CurDAG->SelectNodeTo(N, Opc, MVT::i32,Ops, 6); 1691 } 1692 return 0; 1693} 1694 1695SDNode *ARMDAGToDAGISel:: 1696SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1697 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1698 SDValue CPTmp0; 1699 SDValue CPTmp1; 1700 SDValue CPTmp2; 1701 if (SelectShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1, CPTmp2)) { 1702 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1703 SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag }; 1704 return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7); 1705 } 1706 return 0; 1707} 1708 1709SDNode *ARMDAGToDAGISel:: 1710SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1711 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1712 ConstantSDNode *T = dyn_cast<ConstantSDNode>(TrueVal); 1713 if (!T) 1714 return 0; 1715 1716 if (Pred_t2_so_imm(TrueVal.getNode())) { 1717 SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32); 1718 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1719 SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag }; 1720 return CurDAG->SelectNodeTo(N, 1721 ARM::t2MOVCCi, MVT::i32, Ops, 5); 1722 } 1723 return 0; 1724} 1725 1726SDNode *ARMDAGToDAGISel:: 1727SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1728 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1729 ConstantSDNode *T = dyn_cast<ConstantSDNode>(TrueVal); 1730 if (!T) 1731 return 0; 1732 1733 if (Pred_so_imm(TrueVal.getNode())) { 1734 SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32); 1735 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1736 SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag }; 1737 return CurDAG->SelectNodeTo(N, 1738 ARM::MOVCCi, MVT::i32, Ops, 5); 1739 } 1740 return 0; 1741} 1742 1743SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDNode *N) { 1744 EVT VT = N->getValueType(0); 1745 SDValue FalseVal = N->getOperand(0); 1746 SDValue TrueVal = N->getOperand(1); 1747 SDValue CC = N->getOperand(2); 1748 SDValue CCR = N->getOperand(3); 1749 SDValue InFlag = N->getOperand(4); 1750 assert(CC.getOpcode() == ISD::Constant); 1751 assert(CCR.getOpcode() == ISD::Register); 1752 ARMCC::CondCodes CCVal = 1753 (ARMCC::CondCodes)cast<ConstantSDNode>(CC)->getZExtValue(); 1754 1755 if (!Subtarget->isThumb1Only() && VT == MVT::i32) { 1756 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1757 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1758 // Pattern complexity = 18 cost = 1 size = 0 1759 SDValue CPTmp0; 1760 SDValue CPTmp1; 1761 SDValue CPTmp2; 1762 if (Subtarget->isThumb()) { 1763 SDNode *Res = SelectT2CMOVShiftOp(N, FalseVal, TrueVal, 1764 CCVal, CCR, InFlag); 1765 if (!Res) 1766 Res = SelectT2CMOVShiftOp(N, TrueVal, FalseVal, 1767 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1768 if (Res) 1769 return Res; 1770 } else { 1771 SDNode *Res = SelectARMCMOVShiftOp(N, FalseVal, TrueVal, 1772 CCVal, CCR, InFlag); 1773 if (!Res) 1774 Res = SelectARMCMOVShiftOp(N, TrueVal, FalseVal, 1775 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1776 if (Res) 1777 return Res; 1778 } 1779 1780 // Pattern: (ARMcmov:i32 GPR:i32:$false, 1781 // (imm:i32)<<P:Pred_so_imm>>:$true, 1782 // (imm:i32):$cc) 1783 // Emits: (MOVCCi:i32 GPR:i32:$false, 1784 // (so_imm:i32 (imm:i32):$true), (imm:i32):$cc) 1785 // Pattern complexity = 10 cost = 1 size = 0 1786 if (Subtarget->isThumb()) { 1787 SDNode *Res = SelectT2CMOVSoImmOp(N, FalseVal, TrueVal, 1788 CCVal, CCR, InFlag); 1789 if (!Res) 1790 Res = SelectT2CMOVSoImmOp(N, TrueVal, FalseVal, 1791 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1792 if (Res) 1793 return Res; 1794 } else { 1795 SDNode *Res = SelectARMCMOVSoImmOp(N, FalseVal, TrueVal, 1796 CCVal, CCR, InFlag); 1797 if (!Res) 1798 Res = SelectARMCMOVSoImmOp(N, TrueVal, FalseVal, 1799 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1800 if (Res) 1801 return Res; 1802 } 1803 } 1804 1805 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1806 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1807 // Pattern complexity = 6 cost = 1 size = 0 1808 // 1809 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1810 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1811 // Pattern complexity = 6 cost = 11 size = 0 1812 // 1813 // Also FCPYScc and FCPYDcc. 1814 SDValue Tmp2 = CurDAG->getTargetConstant(CCVal, MVT::i32); 1815 SDValue Ops[] = { FalseVal, TrueVal, Tmp2, CCR, InFlag }; 1816 unsigned Opc = 0; 1817 switch (VT.getSimpleVT().SimpleTy) { 1818 default: assert(false && "Illegal conditional move type!"); 1819 break; 1820 case MVT::i32: 1821 Opc = Subtarget->isThumb() 1822 ? (Subtarget->hasThumb2() ? ARM::t2MOVCCr : ARM::tMOVCCr_pseudo) 1823 : ARM::MOVCCr; 1824 break; 1825 case MVT::f32: 1826 Opc = ARM::VMOVScc; 1827 break; 1828 case MVT::f64: 1829 Opc = ARM::VMOVDcc; 1830 break; 1831 } 1832 return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5); 1833} 1834 1835SDNode *ARMDAGToDAGISel::SelectConcatVector(SDNode *N) { 1836 // The only time a CONCAT_VECTORS operation can have legal types is when 1837 // two 64-bit vectors are concatenated to a 128-bit vector. 1838 EVT VT = N->getValueType(0); 1839 if (!VT.is128BitVector() || N->getNumOperands() != 2) 1840 llvm_unreachable("unexpected CONCAT_VECTORS"); 1841 DebugLoc dl = N->getDebugLoc(); 1842 SDValue V0 = N->getOperand(0); 1843 SDValue V1 = N->getOperand(1); 1844 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32); 1845 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32); 1846 const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 }; 1847 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4); 1848} 1849 1850SDNode *ARMDAGToDAGISel::Select(SDNode *N) { 1851 DebugLoc dl = N->getDebugLoc(); 1852 1853 if (N->isMachineOpcode()) 1854 return NULL; // Already selected. 1855 1856 switch (N->getOpcode()) { 1857 default: break; 1858 case ISD::Constant: { 1859 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 1860 bool UseCP = true; 1861 if (Subtarget->hasThumb2()) 1862 // Thumb2-aware targets have the MOVT instruction, so all immediates can 1863 // be done with MOV + MOVT, at worst. 1864 UseCP = 0; 1865 else { 1866 if (Subtarget->isThumb()) { 1867 UseCP = (Val > 255 && // MOV 1868 ~Val > 255 && // MOV + MVN 1869 !ARM_AM::isThumbImmShiftedVal(Val)); // MOV + LSL 1870 } else 1871 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV 1872 ARM_AM::getSOImmVal(~Val) == -1 && // MVN 1873 !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs. 1874 } 1875 1876 if (UseCP) { 1877 SDValue CPIdx = 1878 CurDAG->getTargetConstantPool(ConstantInt::get( 1879 Type::getInt32Ty(*CurDAG->getContext()), Val), 1880 TLI.getPointerTy()); 1881 1882 SDNode *ResNode; 1883 if (Subtarget->isThumb1Only()) { 1884 SDValue Pred = getAL(CurDAG); 1885 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1886 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() }; 1887 ResNode = CurDAG->getMachineNode(ARM::tLDRcp, dl, MVT::i32, MVT::Other, 1888 Ops, 4); 1889 } else { 1890 SDValue Ops[] = { 1891 CPIdx, 1892 CurDAG->getRegister(0, MVT::i32), 1893 CurDAG->getTargetConstant(0, MVT::i32), 1894 getAL(CurDAG), 1895 CurDAG->getRegister(0, MVT::i32), 1896 CurDAG->getEntryNode() 1897 }; 1898 ResNode=CurDAG->getMachineNode(ARM::LDRcp, dl, MVT::i32, MVT::Other, 1899 Ops, 6); 1900 } 1901 ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0)); 1902 return NULL; 1903 } 1904 1905 // Other cases are autogenerated. 1906 break; 1907 } 1908 case ISD::FrameIndex: { 1909 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. 1910 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1911 SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 1912 if (Subtarget->isThumb1Only()) { 1913 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI, 1914 CurDAG->getTargetConstant(0, MVT::i32)); 1915 } else { 1916 unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ? 1917 ARM::t2ADDri : ARM::ADDri); 1918 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), 1919 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1920 CurDAG->getRegister(0, MVT::i32) }; 1921 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); 1922 } 1923 } 1924 case ISD::SRL: 1925 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, false)) 1926 return I; 1927 break; 1928 case ISD::SRA: 1929 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, true)) 1930 return I; 1931 break; 1932 case ISD::MUL: 1933 if (Subtarget->isThumb1Only()) 1934 break; 1935 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) { 1936 unsigned RHSV = C->getZExtValue(); 1937 if (!RHSV) break; 1938 if (isPowerOf2_32(RHSV-1)) { // 2^n+1? 1939 unsigned ShImm = Log2_32(RHSV-1); 1940 if (ShImm >= 32) 1941 break; 1942 SDValue V = N->getOperand(0); 1943 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 1944 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); 1945 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1946 if (Subtarget->isThumb()) { 1947 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1948 return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops, 6); 1949 } else { 1950 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1951 return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7); 1952 } 1953 } 1954 if (isPowerOf2_32(RHSV+1)) { // 2^n-1? 1955 unsigned ShImm = Log2_32(RHSV+1); 1956 if (ShImm >= 32) 1957 break; 1958 SDValue V = N->getOperand(0); 1959 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 1960 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); 1961 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1962 if (Subtarget->isThumb()) { 1963 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1964 return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops, 6); 1965 } else { 1966 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1967 return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7); 1968 } 1969 } 1970 } 1971 break; 1972 case ISD::AND: { 1973 // Check for unsigned bitfield extract 1974 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, false)) 1975 return I; 1976 1977 // (and (or x, c2), c1) and top 16-bits of c1 and c2 match, lower 16-bits 1978 // of c1 are 0xffff, and lower 16-bit of c2 are 0. That is, the top 16-bits 1979 // are entirely contributed by c2 and lower 16-bits are entirely contributed 1980 // by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)). 1981 // Select it to: "movt x, ((c1 & 0xffff) >> 16) 1982 EVT VT = N->getValueType(0); 1983 if (VT != MVT::i32) 1984 break; 1985 unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2()) 1986 ? ARM::t2MOVTi16 1987 : (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0); 1988 if (!Opc) 1989 break; 1990 SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); 1991 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 1992 if (!N1C) 1993 break; 1994 if (N0.getOpcode() == ISD::OR && N0.getNode()->hasOneUse()) { 1995 SDValue N2 = N0.getOperand(1); 1996 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2); 1997 if (!N2C) 1998 break; 1999 unsigned N1CVal = N1C->getZExtValue(); 2000 unsigned N2CVal = N2C->getZExtValue(); 2001 if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) && 2002 (N1CVal & 0xffffU) == 0xffffU && 2003 (N2CVal & 0xffffU) == 0x0U) { 2004 SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16, 2005 MVT::i32); 2006 SDValue Ops[] = { N0.getOperand(0), Imm16, 2007 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; 2008 return CurDAG->getMachineNode(Opc, dl, VT, Ops, 4); 2009 } 2010 } 2011 break; 2012 } 2013 case ARMISD::VMOVRRD: 2014 return CurDAG->getMachineNode(ARM::VMOVRRD, dl, MVT::i32, MVT::i32, 2015 N->getOperand(0), getAL(CurDAG), 2016 CurDAG->getRegister(0, MVT::i32)); 2017 case ISD::UMUL_LOHI: { 2018 if (Subtarget->isThumb1Only()) 2019 break; 2020 if (Subtarget->isThumb()) { 2021 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 2022 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 2023 CurDAG->getRegister(0, MVT::i32) }; 2024 return CurDAG->getMachineNode(ARM::t2UMULL, dl, MVT::i32, MVT::i32,Ops,4); 2025 } else { 2026 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 2027 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 2028 CurDAG->getRegister(0, MVT::i32) }; 2029 return CurDAG->getMachineNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5); 2030 } 2031 } 2032 case ISD::SMUL_LOHI: { 2033 if (Subtarget->isThumb1Only()) 2034 break; 2035 if (Subtarget->isThumb()) { 2036 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 2037 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; 2038 return CurDAG->getMachineNode(ARM::t2SMULL, dl, MVT::i32, MVT::i32,Ops,4); 2039 } else { 2040 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 2041 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 2042 CurDAG->getRegister(0, MVT::i32) }; 2043 return CurDAG->getMachineNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5); 2044 } 2045 } 2046 case ISD::LOAD: { 2047 SDNode *ResNode = 0; 2048 if (Subtarget->isThumb() && Subtarget->hasThumb2()) 2049 ResNode = SelectT2IndexedLoad(N); 2050 else 2051 ResNode = SelectARMIndexedLoad(N); 2052 if (ResNode) 2053 return ResNode; 2054 2055 // VLDMQ must be custom-selected for "v2f64 load" to set the AM5Opc value. 2056 if (Subtarget->hasVFP2() && 2057 N->getValueType(0).getSimpleVT().SimpleTy == MVT::v2f64) { 2058 SDValue Chain = N->getOperand(0); 2059 SDValue AM5Opc = 2060 CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::ia, 4), MVT::i32); 2061 SDValue Pred = getAL(CurDAG); 2062 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 2063 SDValue Ops[] = { N->getOperand(1), AM5Opc, Pred, PredReg, Chain }; 2064 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 2065 MemOp[0] = cast<MemSDNode>(N)->getMemOperand(); 2066 SDNode *Ret = CurDAG->getMachineNode(ARM::VLDMQ, dl, 2067 MVT::v2f64, MVT::Other, Ops, 5); 2068 cast<MachineSDNode>(Ret)->setMemRefs(MemOp, MemOp + 1); 2069 return Ret; 2070 } 2071 // Other cases are autogenerated. 2072 break; 2073 } 2074 case ISD::STORE: { 2075 // VSTMQ must be custom-selected for "v2f64 store" to set the AM5Opc value. 2076 if (Subtarget->hasVFP2() && 2077 N->getOperand(1).getValueType().getSimpleVT().SimpleTy == MVT::v2f64) { 2078 SDValue Chain = N->getOperand(0); 2079 SDValue AM5Opc = 2080 CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::ia, 4), MVT::i32); 2081 SDValue Pred = getAL(CurDAG); 2082 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 2083 SDValue Ops[] = { N->getOperand(1), N->getOperand(2), 2084 AM5Opc, Pred, PredReg, Chain }; 2085 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 2086 MemOp[0] = cast<MemSDNode>(N)->getMemOperand(); 2087 SDNode *Ret = CurDAG->getMachineNode(ARM::VSTMQ, dl, MVT::Other, Ops, 6); 2088 cast<MachineSDNode>(Ret)->setMemRefs(MemOp, MemOp + 1); 2089 return Ret; 2090 } 2091 // Other cases are autogenerated. 2092 break; 2093 } 2094 case ARMISD::BRCOND: { 2095 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 2096 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc) 2097 // Pattern complexity = 6 cost = 1 size = 0 2098 2099 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 2100 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc) 2101 // Pattern complexity = 6 cost = 1 size = 0 2102 2103 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 2104 // Emits: (t2Bcc:void (bb:Other):$dst, (imm:i32):$cc) 2105 // Pattern complexity = 6 cost = 1 size = 0 2106 2107 unsigned Opc = Subtarget->isThumb() ? 2108 ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; 2109 SDValue Chain = N->getOperand(0); 2110 SDValue N1 = N->getOperand(1); 2111 SDValue N2 = N->getOperand(2); 2112 SDValue N3 = N->getOperand(3); 2113 SDValue InFlag = N->getOperand(4); 2114 assert(N1.getOpcode() == ISD::BasicBlock); 2115 assert(N2.getOpcode() == ISD::Constant); 2116 assert(N3.getOpcode() == ISD::Register); 2117 2118 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 2119 cast<ConstantSDNode>(N2)->getZExtValue()), 2120 MVT::i32); 2121 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; 2122 SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, 2123 MVT::Flag, Ops, 5); 2124 Chain = SDValue(ResNode, 0); 2125 if (N->getNumValues() == 2) { 2126 InFlag = SDValue(ResNode, 1); 2127 ReplaceUses(SDValue(N, 1), InFlag); 2128 } 2129 ReplaceUses(SDValue(N, 0), 2130 SDValue(Chain.getNode(), Chain.getResNo())); 2131 return NULL; 2132 } 2133 case ARMISD::CMOV: 2134 return SelectCMOVOp(N); 2135 case ARMISD::CNEG: { 2136 EVT VT = N->getValueType(0); 2137 SDValue N0 = N->getOperand(0); 2138 SDValue N1 = N->getOperand(1); 2139 SDValue N2 = N->getOperand(2); 2140 SDValue N3 = N->getOperand(3); 2141 SDValue InFlag = N->getOperand(4); 2142 assert(N2.getOpcode() == ISD::Constant); 2143 assert(N3.getOpcode() == ISD::Register); 2144 2145 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 2146 cast<ConstantSDNode>(N2)->getZExtValue()), 2147 MVT::i32); 2148 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 2149 unsigned Opc = 0; 2150 switch (VT.getSimpleVT().SimpleTy) { 2151 default: assert(false && "Illegal conditional move type!"); 2152 break; 2153 case MVT::f32: 2154 Opc = ARM::VNEGScc; 2155 break; 2156 case MVT::f64: 2157 Opc = ARM::VNEGDcc; 2158 break; 2159 } 2160 return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5); 2161 } 2162 2163 case ARMISD::VZIP: { 2164 unsigned Opc = 0; 2165 EVT VT = N->getValueType(0); 2166 switch (VT.getSimpleVT().SimpleTy) { 2167 default: return NULL; 2168 case MVT::v8i8: Opc = ARM::VZIPd8; break; 2169 case MVT::v4i16: Opc = ARM::VZIPd16; break; 2170 case MVT::v2f32: 2171 case MVT::v2i32: Opc = ARM::VZIPd32; break; 2172 case MVT::v16i8: Opc = ARM::VZIPq8; break; 2173 case MVT::v8i16: Opc = ARM::VZIPq16; break; 2174 case MVT::v4f32: 2175 case MVT::v4i32: Opc = ARM::VZIPq32; break; 2176 } 2177 SDValue Pred = getAL(CurDAG); 2178 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 2179 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 2180 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); 2181 } 2182 case ARMISD::VUZP: { 2183 unsigned Opc = 0; 2184 EVT VT = N->getValueType(0); 2185 switch (VT.getSimpleVT().SimpleTy) { 2186 default: return NULL; 2187 case MVT::v8i8: Opc = ARM::VUZPd8; break; 2188 case MVT::v4i16: Opc = ARM::VUZPd16; break; 2189 case MVT::v2f32: 2190 case MVT::v2i32: Opc = ARM::VUZPd32; break; 2191 case MVT::v16i8: Opc = ARM::VUZPq8; break; 2192 case MVT::v8i16: Opc = ARM::VUZPq16; break; 2193 case MVT::v4f32: 2194 case MVT::v4i32: Opc = ARM::VUZPq32; break; 2195 } 2196 SDValue Pred = getAL(CurDAG); 2197 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 2198 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 2199 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); 2200 } 2201 case ARMISD::VTRN: { 2202 unsigned Opc = 0; 2203 EVT VT = N->getValueType(0); 2204 switch (VT.getSimpleVT().SimpleTy) { 2205 default: return NULL; 2206 case MVT::v8i8: Opc = ARM::VTRNd8; break; 2207 case MVT::v4i16: Opc = ARM::VTRNd16; break; 2208 case MVT::v2f32: 2209 case MVT::v2i32: Opc = ARM::VTRNd32; break; 2210 case MVT::v16i8: Opc = ARM::VTRNq8; break; 2211 case MVT::v8i16: Opc = ARM::VTRNq16; break; 2212 case MVT::v4f32: 2213 case MVT::v4i32: Opc = ARM::VTRNq32; break; 2214 } 2215 SDValue Pred = getAL(CurDAG); 2216 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 2217 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 2218 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); 2219 } 2220 case ARMISD::BUILD_VECTOR: { 2221 EVT VecVT = N->getValueType(0); 2222 EVT EltVT = VecVT.getVectorElementType(); 2223 unsigned NumElts = VecVT.getVectorNumElements(); 2224 if (EltVT.getSimpleVT() == MVT::f64) { 2225 assert(NumElts == 2 && "unexpected type for BUILD_VECTOR"); 2226 return PairDRegs(VecVT, N->getOperand(0), N->getOperand(1)); 2227 } 2228 assert(EltVT.getSimpleVT() == MVT::f32 && 2229 "unexpected type for BUILD_VECTOR"); 2230 if (NumElts == 2) 2231 return PairSRegs(VecVT, N->getOperand(0), N->getOperand(1)); 2232 assert(NumElts == 4 && "unexpected type for BUILD_VECTOR"); 2233 return QuadSRegs(VecVT, N->getOperand(0), N->getOperand(1), 2234 N->getOperand(2), N->getOperand(3)); 2235 } 2236 2237 case ISD::INTRINSIC_VOID: 2238 case ISD::INTRINSIC_W_CHAIN: { 2239 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 2240 switch (IntNo) { 2241 default: 2242 break; 2243 2244 case Intrinsic::arm_neon_vld1: { 2245 unsigned DOpcodes[] = { ARM::VLD1d8, ARM::VLD1d16, 2246 ARM::VLD1d32, ARM::VLD1d64 }; 2247 unsigned QOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16, 2248 ARM::VLD1q32, ARM::VLD1q64 }; 2249 return SelectVLD(N, 1, DOpcodes, QOpcodes, 0); 2250 } 2251 2252 case Intrinsic::arm_neon_vld2: { 2253 unsigned DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16, 2254 ARM::VLD2d32, ARM::VLD1q64 }; 2255 unsigned QOpcodes[] = { ARM::VLD2q8, ARM::VLD2q16, ARM::VLD2q32 }; 2256 return SelectVLD(N, 2, DOpcodes, QOpcodes, 0); 2257 } 2258 2259 case Intrinsic::arm_neon_vld3: { 2260 unsigned DOpcodes[] = { ARM::VLD3d8, ARM::VLD3d16, 2261 ARM::VLD3d32, ARM::VLD1d64T }; 2262 unsigned QOpcodes0[] = { ARM::VLD3q8_UPD, 2263 ARM::VLD3q16_UPD, 2264 ARM::VLD3q32_UPD }; 2265 unsigned QOpcodes1[] = { ARM::VLD3q8odd_UPD, 2266 ARM::VLD3q16odd_UPD, 2267 ARM::VLD3q32odd_UPD }; 2268 return SelectVLD(N, 3, DOpcodes, QOpcodes0, QOpcodes1); 2269 } 2270 2271 case Intrinsic::arm_neon_vld4: { 2272 unsigned DOpcodes[] = { ARM::VLD4d8, ARM::VLD4d16, 2273 ARM::VLD4d32, ARM::VLD1d64Q }; 2274 unsigned QOpcodes0[] = { ARM::VLD4q8_UPD, 2275 ARM::VLD4q16_UPD, 2276 ARM::VLD4q32_UPD }; 2277 unsigned QOpcodes1[] = { ARM::VLD4q8odd_UPD, 2278 ARM::VLD4q16odd_UPD, 2279 ARM::VLD4q32odd_UPD }; 2280 return SelectVLD(N, 4, DOpcodes, QOpcodes0, QOpcodes1); 2281 } 2282 2283 case Intrinsic::arm_neon_vld2lane: { 2284 unsigned DOpcodes[] = { ARM::VLD2LNd8, ARM::VLD2LNd16, ARM::VLD2LNd32 }; 2285 unsigned QOpcodes0[] = { ARM::VLD2LNq16, ARM::VLD2LNq32 }; 2286 unsigned QOpcodes1[] = { ARM::VLD2LNq16odd, ARM::VLD2LNq32odd }; 2287 return SelectVLDSTLane(N, true, 2, DOpcodes, QOpcodes0, QOpcodes1); 2288 } 2289 2290 case Intrinsic::arm_neon_vld3lane: { 2291 unsigned DOpcodes[] = { ARM::VLD3LNd8, ARM::VLD3LNd16, ARM::VLD3LNd32 }; 2292 unsigned QOpcodes0[] = { ARM::VLD3LNq16, ARM::VLD3LNq32 }; 2293 unsigned QOpcodes1[] = { ARM::VLD3LNq16odd, ARM::VLD3LNq32odd }; 2294 return SelectVLDSTLane(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1); 2295 } 2296 2297 case Intrinsic::arm_neon_vld4lane: { 2298 unsigned DOpcodes[] = { ARM::VLD4LNd8, ARM::VLD4LNd16, ARM::VLD4LNd32 }; 2299 unsigned QOpcodes0[] = { ARM::VLD4LNq16, ARM::VLD4LNq32 }; 2300 unsigned QOpcodes1[] = { ARM::VLD4LNq16odd, ARM::VLD4LNq32odd }; 2301 return SelectVLDSTLane(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1); 2302 } 2303 2304 case Intrinsic::arm_neon_vst1: { 2305 unsigned DOpcodes[] = { ARM::VST1d8, ARM::VST1d16, 2306 ARM::VST1d32, ARM::VST1d64 }; 2307 unsigned QOpcodes[] = { ARM::VST1q8, ARM::VST1q16, 2308 ARM::VST1q32, ARM::VST1q64 }; 2309 return SelectVST(N, 1, DOpcodes, QOpcodes, 0); 2310 } 2311 2312 case Intrinsic::arm_neon_vst2: { 2313 unsigned DOpcodes[] = { ARM::VST2d8, ARM::VST2d16, 2314 ARM::VST2d32, ARM::VST1q64 }; 2315 unsigned QOpcodes[] = { ARM::VST2q8, ARM::VST2q16, ARM::VST2q32 }; 2316 return SelectVST(N, 2, DOpcodes, QOpcodes, 0); 2317 } 2318 2319 case Intrinsic::arm_neon_vst3: { 2320 unsigned DOpcodes[] = { ARM::VST3d8Pseudo, ARM::VST3d16Pseudo, 2321 ARM::VST3d32Pseudo, ARM::VST1d64TPseudo }; 2322 unsigned QOpcodes0[] = { ARM::VST3q8Pseudo_UPD, 2323 ARM::VST3q16Pseudo_UPD, 2324 ARM::VST3q32Pseudo_UPD }; 2325 unsigned QOpcodes1[] = { ARM::VST3q8oddPseudo_UPD, 2326 ARM::VST3q16oddPseudo_UPD, 2327 ARM::VST3q32oddPseudo_UPD }; 2328 return SelectVST(N, 3, DOpcodes, QOpcodes0, QOpcodes1); 2329 } 2330 2331 case Intrinsic::arm_neon_vst4: { 2332 unsigned DOpcodes[] = { ARM::VST4d8Pseudo, ARM::VST4d16Pseudo, 2333 ARM::VST4d32Pseudo, ARM::VST1d64QPseudo }; 2334 unsigned QOpcodes0[] = { ARM::VST4q8Pseudo_UPD, 2335 ARM::VST4q16Pseudo_UPD, 2336 ARM::VST4q32Pseudo_UPD }; 2337 unsigned QOpcodes1[] = { ARM::VST4q8oddPseudo_UPD, 2338 ARM::VST4q16oddPseudo_UPD, 2339 ARM::VST4q32oddPseudo_UPD }; 2340 return SelectVST(N, 4, DOpcodes, QOpcodes0, QOpcodes1); 2341 } 2342 2343 case Intrinsic::arm_neon_vst2lane: { 2344 unsigned DOpcodes[] = { ARM::VST2LNd8, ARM::VST2LNd16, ARM::VST2LNd32 }; 2345 unsigned QOpcodes0[] = { ARM::VST2LNq16, ARM::VST2LNq32 }; 2346 unsigned QOpcodes1[] = { ARM::VST2LNq16odd, ARM::VST2LNq32odd }; 2347 return SelectVLDSTLane(N, false, 2, DOpcodes, QOpcodes0, QOpcodes1); 2348 } 2349 2350 case Intrinsic::arm_neon_vst3lane: { 2351 unsigned DOpcodes[] = { ARM::VST3LNd8, ARM::VST3LNd16, ARM::VST3LNd32 }; 2352 unsigned QOpcodes0[] = { ARM::VST3LNq16, ARM::VST3LNq32 }; 2353 unsigned QOpcodes1[] = { ARM::VST3LNq16odd, ARM::VST3LNq32odd }; 2354 return SelectVLDSTLane(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); 2355 } 2356 2357 case Intrinsic::arm_neon_vst4lane: { 2358 unsigned DOpcodes[] = { ARM::VST4LNd8, ARM::VST4LNd16, ARM::VST4LNd32 }; 2359 unsigned QOpcodes0[] = { ARM::VST4LNq16, ARM::VST4LNq32 }; 2360 unsigned QOpcodes1[] = { ARM::VST4LNq16odd, ARM::VST4LNq32odd }; 2361 return SelectVLDSTLane(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); 2362 } 2363 } 2364 break; 2365 } 2366 2367 case ISD::INTRINSIC_WO_CHAIN: { 2368 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 2369 switch (IntNo) { 2370 default: 2371 break; 2372 2373 case Intrinsic::arm_neon_vtbl2: 2374 return SelectVTBL(N, false, 2, ARM::VTBL2); 2375 case Intrinsic::arm_neon_vtbl3: 2376 return SelectVTBL(N, false, 3, ARM::VTBL3); 2377 case Intrinsic::arm_neon_vtbl4: 2378 return SelectVTBL(N, false, 4, ARM::VTBL4); 2379 2380 case Intrinsic::arm_neon_vtbx2: 2381 return SelectVTBL(N, true, 2, ARM::VTBX2); 2382 case Intrinsic::arm_neon_vtbx3: 2383 return SelectVTBL(N, true, 3, ARM::VTBX3); 2384 case Intrinsic::arm_neon_vtbx4: 2385 return SelectVTBL(N, true, 4, ARM::VTBX4); 2386 } 2387 break; 2388 } 2389 2390 case ISD::CONCAT_VECTORS: 2391 return SelectConcatVector(N); 2392 } 2393 2394 return SelectCode(N); 2395} 2396 2397bool ARMDAGToDAGISel:: 2398SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 2399 std::vector<SDValue> &OutOps) { 2400 assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); 2401 // Require the address to be in a register. That is safe for all ARM 2402 // variants and it is hard to do anything much smarter without knowing 2403 // how the operand is used. 2404 OutOps.push_back(Op); 2405 return false; 2406} 2407 2408/// createARMISelDag - This pass converts a legalized DAG into a 2409/// ARM-specific DAG, ready for instruction scheduling. 2410/// 2411FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM, 2412 CodeGenOpt::Level OptLevel) { 2413 return new ARMDAGToDAGISel(TM, OptLevel); 2414} 2415