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