ARMISelDAGToDAG.cpp revision 207631
1254885Sdumbbell//===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// 2254885Sdumbbell// 3254885Sdumbbell// The LLVM Compiler Infrastructure 4254885Sdumbbell// 5254885Sdumbbell// This file is distributed under the University of Illinois Open Source 6254885Sdumbbell// License. See LICENSE.TXT for details. 7254885Sdumbbell// 8254885Sdumbbell//===----------------------------------------------------------------------===// 9254885Sdumbbell// 10254885Sdumbbell// This file defines an instruction selector for the ARM target. 11254885Sdumbbell// 12254885Sdumbbell//===----------------------------------------------------------------------===// 13254885Sdumbbell 14254885Sdumbbell#include "ARM.h" 15254885Sdumbbell#include "ARMAddressingModes.h" 16254885Sdumbbell#include "ARMTargetMachine.h" 17254885Sdumbbell#include "llvm/CallingConv.h" 18254885Sdumbbell#include "llvm/Constants.h" 19254885Sdumbbell#include "llvm/DerivedTypes.h" 20254885Sdumbbell#include "llvm/Function.h" 21254885Sdumbbell#include "llvm/Intrinsics.h" 22254885Sdumbbell#include "llvm/LLVMContext.h" 23254885Sdumbbell#include "llvm/CodeGen/MachineFrameInfo.h" 24254885Sdumbbell#include "llvm/CodeGen/MachineFunction.h" 25254885Sdumbbell#include "llvm/CodeGen/MachineInstrBuilder.h" 26254885Sdumbbell#include "llvm/CodeGen/SelectionDAG.h" 27254885Sdumbbell#include "llvm/CodeGen/SelectionDAGISel.h" 28254885Sdumbbell#include "llvm/Target/TargetLowering.h" 29254885Sdumbbell#include "llvm/Target/TargetOptions.h" 30254885Sdumbbell#include "llvm/Support/CommandLine.h" 31254885Sdumbbell#include "llvm/Support/Compiler.h" 32254885Sdumbbell#include "llvm/Support/Debug.h" 33254885Sdumbbell#include "llvm/Support/ErrorHandling.h" 34254885Sdumbbell#include "llvm/Support/raw_ostream.h" 35254885Sdumbbell 36254885Sdumbbellusing namespace llvm; 37254885Sdumbbell 38254885Sdumbbellstatic cl::opt<bool> 39254885SdumbbellUseRegSeq("neon-reg-sequence", cl::Hidden, 40254885Sdumbbell cl::desc("Use reg_sequence to model ld / st of multiple neon regs")); 41254885Sdumbbell 42254885Sdumbbell//===--------------------------------------------------------------------===// 43254885Sdumbbell/// ARMDAGToDAGISel - ARM specific code to select ARM machine 44254885Sdumbbell/// instructions for SelectionDAG operations. 45254885Sdumbbell/// 46254885Sdumbbellnamespace { 47254885Sdumbbellclass ARMDAGToDAGISel : public SelectionDAGISel { 48254885Sdumbbell ARMBaseTargetMachine &TM; 49254885Sdumbbell 50254885Sdumbbell /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 51254885Sdumbbell /// make the right decision when generating code for different targets. 52254885Sdumbbell const ARMSubtarget *Subtarget; 53254885Sdumbbell 54254885Sdumbbellpublic: 55254885Sdumbbell explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm, 56254885Sdumbbell CodeGenOpt::Level OptLevel) 57254885Sdumbbell : SelectionDAGISel(tm, OptLevel), TM(tm), 58254885Sdumbbell Subtarget(&TM.getSubtarget<ARMSubtarget>()) { 59254885Sdumbbell } 60254885Sdumbbell 61254885Sdumbbell virtual const char *getPassName() const { 62254885Sdumbbell return "ARM Instruction Selection"; 63254885Sdumbbell } 64254885Sdumbbell 65254885Sdumbbell /// getI32Imm - Return a target constant of type i32 with the specified 66254885Sdumbbell /// value. 67254885Sdumbbell inline SDValue getI32Imm(unsigned Imm) { 68254885Sdumbbell return CurDAG->getTargetConstant(Imm, MVT::i32); 69254885Sdumbbell } 70254885Sdumbbell 71254885Sdumbbell SDNode *Select(SDNode *N); 72254885Sdumbbell 73254885Sdumbbell bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A, 74254885Sdumbbell SDValue &B, SDValue &C); 75254885Sdumbbell bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base, 76254885Sdumbbell SDValue &Offset, SDValue &Opc); 77254885Sdumbbell bool SelectAddrMode2Offset(SDNode *Op, SDValue N, 78254885Sdumbbell SDValue &Offset, SDValue &Opc); 79254885Sdumbbell bool SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base, 80254885Sdumbbell SDValue &Offset, SDValue &Opc); 81254885Sdumbbell bool SelectAddrMode3Offset(SDNode *Op, SDValue N, 82254885Sdumbbell SDValue &Offset, SDValue &Opc); 83254885Sdumbbell bool SelectAddrMode4(SDNode *Op, SDValue N, SDValue &Addr, 84254885Sdumbbell SDValue &Mode); 85254885Sdumbbell bool SelectAddrMode5(SDNode *Op, SDValue N, SDValue &Base, 86254885Sdumbbell SDValue &Offset); 87254885Sdumbbell bool SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Align); 88254885Sdumbbell 89254885Sdumbbell bool SelectAddrModePC(SDNode *Op, SDValue N, SDValue &Offset, 90254885Sdumbbell SDValue &Label); 91254885Sdumbbell 92254885Sdumbbell bool SelectThumbAddrModeRR(SDNode *Op, SDValue N, SDValue &Base, 93254885Sdumbbell SDValue &Offset); 94254885Sdumbbell bool SelectThumbAddrModeRI5(SDNode *Op, SDValue N, unsigned Scale, 95254885Sdumbbell SDValue &Base, SDValue &OffImm, 96254885Sdumbbell SDValue &Offset); 97254885Sdumbbell bool SelectThumbAddrModeS1(SDNode *Op, SDValue N, SDValue &Base, 98254885Sdumbbell SDValue &OffImm, SDValue &Offset); 99254885Sdumbbell bool SelectThumbAddrModeS2(SDNode *Op, SDValue N, SDValue &Base, 100254885Sdumbbell SDValue &OffImm, SDValue &Offset); 101254885Sdumbbell bool SelectThumbAddrModeS4(SDNode *Op, SDValue N, SDValue &Base, 102254885Sdumbbell SDValue &OffImm, SDValue &Offset); 103254885Sdumbbell bool SelectThumbAddrModeSP(SDNode *Op, SDValue N, SDValue &Base, 104254885Sdumbbell SDValue &OffImm); 105254885Sdumbbell 106254885Sdumbbell bool SelectT2ShifterOperandReg(SDNode *Op, SDValue N, 107254885Sdumbbell SDValue &BaseReg, SDValue &Opc); 108254885Sdumbbell bool SelectT2AddrModeImm12(SDNode *Op, SDValue N, SDValue &Base, 109254885Sdumbbell SDValue &OffImm); 110254885Sdumbbell bool SelectT2AddrModeImm8(SDNode *Op, SDValue N, SDValue &Base, 111254885Sdumbbell SDValue &OffImm); 112254885Sdumbbell bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 113254885Sdumbbell SDValue &OffImm); 114254885Sdumbbell bool SelectT2AddrModeImm8s4(SDNode *Op, SDValue N, SDValue &Base, 115254885Sdumbbell SDValue &OffImm); 116254885Sdumbbell bool SelectT2AddrModeSoReg(SDNode *Op, SDValue N, SDValue &Base, 117254885Sdumbbell SDValue &OffReg, SDValue &ShImm); 118254885Sdumbbell 119254885Sdumbbell // Include the pieces autogenerated from the target description. 120254885Sdumbbell#include "ARMGenDAGISel.inc" 121254885Sdumbbell 122254885Sdumbbellprivate: 123254885Sdumbbell /// SelectARMIndexedLoad - Indexed (pre/post inc/dec) load matching code for 124254885Sdumbbell /// ARM. 125254885Sdumbbell SDNode *SelectARMIndexedLoad(SDNode *N); 126254885Sdumbbell SDNode *SelectT2IndexedLoad(SDNode *N); 127254885Sdumbbell 128254885Sdumbbell /// SelectVLD - Select NEON load intrinsics. NumVecs should be 129254885Sdumbbell /// 1, 2, 3 or 4. The opcode arrays specify the instructions used for 130254885Sdumbbell /// loads of D registers and even subregs and odd subregs of Q registers. 131254885Sdumbbell /// For NumVecs <= 2, QOpcodes1 is not used. 132254885Sdumbbell SDNode *SelectVLD(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, 133254885Sdumbbell unsigned *QOpcodes0, unsigned *QOpcodes1); 134254885Sdumbbell 135254885Sdumbbell /// SelectVST - Select NEON store intrinsics. NumVecs should 136254885Sdumbbell /// be 1, 2, 3 or 4. The opcode arrays specify the instructions used for 137254885Sdumbbell /// stores of D registers and even subregs and odd subregs of Q registers. 138254885Sdumbbell /// For NumVecs <= 2, QOpcodes1 is not used. 139254885Sdumbbell SDNode *SelectVST(SDNode *N, unsigned NumVecs, unsigned *DOpcodes, 140254885Sdumbbell unsigned *QOpcodes0, unsigned *QOpcodes1); 141254885Sdumbbell 142254885Sdumbbell /// SelectVLDSTLane - Select NEON load/store lane intrinsics. NumVecs should 143254885Sdumbbell /// be 2, 3 or 4. The opcode arrays specify the instructions used for 144254885Sdumbbell /// load/store of D registers and even subregs and odd subregs of Q registers. 145254885Sdumbbell SDNode *SelectVLDSTLane(SDNode *N, bool IsLoad, unsigned NumVecs, 146254885Sdumbbell unsigned *DOpcodes, unsigned *QOpcodes0, 147254885Sdumbbell unsigned *QOpcodes1); 148254885Sdumbbell 149254885Sdumbbell /// SelectV6T2BitfieldExtractOp - Select SBFX/UBFX instructions for ARM. 150254885Sdumbbell SDNode *SelectV6T2BitfieldExtractOp(SDNode *N, bool isSigned); 151254885Sdumbbell 152254885Sdumbbell /// SelectCMOVOp - Select CMOV instructions for ARM. 153254885Sdumbbell SDNode *SelectCMOVOp(SDNode *N); 154254885Sdumbbell SDNode *SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 155254885Sdumbbell ARMCC::CondCodes CCVal, SDValue CCR, 156254885Sdumbbell SDValue InFlag); 157254885Sdumbbell SDNode *SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 158254885Sdumbbell ARMCC::CondCodes CCVal, SDValue CCR, 159254885Sdumbbell SDValue InFlag); 160254885Sdumbbell SDNode *SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 161254885Sdumbbell ARMCC::CondCodes CCVal, SDValue CCR, 162254885Sdumbbell SDValue InFlag); 163254885Sdumbbell SDNode *SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 164254885Sdumbbell ARMCC::CondCodes CCVal, SDValue CCR, 165254885Sdumbbell SDValue InFlag); 166254885Sdumbbell 167254885Sdumbbell /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 168254885Sdumbbell /// inline asm expressions. 169254885Sdumbbell virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 170254885Sdumbbell char ConstraintCode, 171254885Sdumbbell std::vector<SDValue> &OutOps); 172254885Sdumbbell 173254885Sdumbbell /// PairDRegs - Insert a pair of double registers into an implicit def to 174254885Sdumbbell /// form a quad register. 175254885Sdumbbell SDNode *PairDRegs(EVT VT, SDValue V0, SDValue V1); 176254885Sdumbbell}; 177254885Sdumbbell} 178254885Sdumbbell 179254885Sdumbbell/// isInt32Immediate - This method tests to see if the node is a 32-bit constant 180254885Sdumbbell/// operand. If so Imm will receive the 32-bit value. 181254885Sdumbbellstatic bool isInt32Immediate(SDNode *N, unsigned &Imm) { 182254885Sdumbbell if (N->getOpcode() == ISD::Constant && N->getValueType(0) == MVT::i32) { 183254885Sdumbbell Imm = cast<ConstantSDNode>(N)->getZExtValue(); 184254885Sdumbbell return true; 185254885Sdumbbell } 186254885Sdumbbell return false; 187254885Sdumbbell} 188254885Sdumbbell 189254885Sdumbbell// isInt32Immediate - This method tests to see if a constant operand. 190254885Sdumbbell// If so Imm will receive the 32 bit value. 191254885Sdumbbellstatic bool isInt32Immediate(SDValue N, unsigned &Imm) { 192254885Sdumbbell return isInt32Immediate(N.getNode(), Imm); 193254885Sdumbbell} 194254885Sdumbbell 195// isOpcWithIntImmediate - This method tests to see if the node is a specific 196// opcode and that it has a immediate integer right operand. 197// If so Imm will receive the 32 bit value. 198static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) { 199 return N->getOpcode() == Opc && 200 isInt32Immediate(N->getOperand(1).getNode(), Imm); 201} 202 203 204bool ARMDAGToDAGISel::SelectShifterOperandReg(SDNode *Op, 205 SDValue N, 206 SDValue &BaseReg, 207 SDValue &ShReg, 208 SDValue &Opc) { 209 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 210 211 // Don't match base register only case. That is matched to a separate 212 // lower complexity pattern with explicit register operand. 213 if (ShOpcVal == ARM_AM::no_shift) return false; 214 215 BaseReg = N.getOperand(0); 216 unsigned ShImmVal = 0; 217 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 218 ShReg = CurDAG->getRegister(0, MVT::i32); 219 ShImmVal = RHS->getZExtValue() & 31; 220 } else { 221 ShReg = N.getOperand(1); 222 } 223 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 224 MVT::i32); 225 return true; 226} 227 228bool ARMDAGToDAGISel::SelectAddrMode2(SDNode *Op, SDValue N, 229 SDValue &Base, SDValue &Offset, 230 SDValue &Opc) { 231 if (N.getOpcode() == ISD::MUL) { 232 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 233 // X * [3,5,9] -> X + X * [2,4,8] etc. 234 int RHSC = (int)RHS->getZExtValue(); 235 if (RHSC & 1) { 236 RHSC = RHSC & ~1; 237 ARM_AM::AddrOpc AddSub = ARM_AM::add; 238 if (RHSC < 0) { 239 AddSub = ARM_AM::sub; 240 RHSC = - RHSC; 241 } 242 if (isPowerOf2_32(RHSC)) { 243 unsigned ShAmt = Log2_32(RHSC); 244 Base = Offset = N.getOperand(0); 245 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, 246 ARM_AM::lsl), 247 MVT::i32); 248 return true; 249 } 250 } 251 } 252 } 253 254 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 255 Base = N; 256 if (N.getOpcode() == ISD::FrameIndex) { 257 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 258 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 259 } else if (N.getOpcode() == ARMISD::Wrapper && 260 !(Subtarget->useMovt() && 261 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 262 Base = N.getOperand(0); 263 } 264 Offset = CurDAG->getRegister(0, MVT::i32); 265 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, 266 ARM_AM::no_shift), 267 MVT::i32); 268 return true; 269 } 270 271 // Match simple R +/- imm12 operands. 272 if (N.getOpcode() == ISD::ADD) 273 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 274 int RHSC = (int)RHS->getZExtValue(); 275 if ((RHSC >= 0 && RHSC < 0x1000) || 276 (RHSC < 0 && RHSC > -0x1000)) { // 12 bits. 277 Base = N.getOperand(0); 278 if (Base.getOpcode() == ISD::FrameIndex) { 279 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 280 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 281 } 282 Offset = CurDAG->getRegister(0, MVT::i32); 283 284 ARM_AM::AddrOpc AddSub = ARM_AM::add; 285 if (RHSC < 0) { 286 AddSub = ARM_AM::sub; 287 RHSC = - RHSC; 288 } 289 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC, 290 ARM_AM::no_shift), 291 MVT::i32); 292 return true; 293 } 294 } 295 296 // Otherwise this is R +/- [possibly shifted] R. 297 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub; 298 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1)); 299 unsigned ShAmt = 0; 300 301 Base = N.getOperand(0); 302 Offset = N.getOperand(1); 303 304 if (ShOpcVal != ARM_AM::no_shift) { 305 // Check to see if the RHS of the shift is a constant, if not, we can't fold 306 // it. 307 if (ConstantSDNode *Sh = 308 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) { 309 ShAmt = Sh->getZExtValue(); 310 Offset = N.getOperand(1).getOperand(0); 311 } else { 312 ShOpcVal = ARM_AM::no_shift; 313 } 314 } 315 316 // Try matching (R shl C) + (R). 317 if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) { 318 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0)); 319 if (ShOpcVal != ARM_AM::no_shift) { 320 // Check to see if the RHS of the shift is a constant, if not, we can't 321 // fold it. 322 if (ConstantSDNode *Sh = 323 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) { 324 ShAmt = Sh->getZExtValue(); 325 Offset = N.getOperand(0).getOperand(0); 326 Base = N.getOperand(1); 327 } else { 328 ShOpcVal = ARM_AM::no_shift; 329 } 330 } 331 } 332 333 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 334 MVT::i32); 335 return true; 336} 337 338bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N, 339 SDValue &Offset, SDValue &Opc) { 340 unsigned Opcode = Op->getOpcode(); 341 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 342 ? cast<LoadSDNode>(Op)->getAddressingMode() 343 : cast<StoreSDNode>(Op)->getAddressingMode(); 344 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 345 ? ARM_AM::add : ARM_AM::sub; 346 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 347 int Val = (int)C->getZExtValue(); 348 if (Val >= 0 && Val < 0x1000) { // 12 bits. 349 Offset = CurDAG->getRegister(0, MVT::i32); 350 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, 351 ARM_AM::no_shift), 352 MVT::i32); 353 return true; 354 } 355 } 356 357 Offset = N; 358 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 359 unsigned ShAmt = 0; 360 if (ShOpcVal != ARM_AM::no_shift) { 361 // Check to see if the RHS of the shift is a constant, if not, we can't fold 362 // it. 363 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 364 ShAmt = Sh->getZExtValue(); 365 Offset = N.getOperand(0); 366 } else { 367 ShOpcVal = ARM_AM::no_shift; 368 } 369 } 370 371 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 372 MVT::i32); 373 return true; 374} 375 376 377bool ARMDAGToDAGISel::SelectAddrMode3(SDNode *Op, SDValue N, 378 SDValue &Base, SDValue &Offset, 379 SDValue &Opc) { 380 if (N.getOpcode() == ISD::SUB) { 381 // X - C is canonicalize to X + -C, no need to handle it here. 382 Base = N.getOperand(0); 383 Offset = N.getOperand(1); 384 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32); 385 return true; 386 } 387 388 if (N.getOpcode() != ISD::ADD) { 389 Base = N; 390 if (N.getOpcode() == ISD::FrameIndex) { 391 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 392 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 393 } 394 Offset = CurDAG->getRegister(0, MVT::i32); 395 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32); 396 return true; 397 } 398 399 // If the RHS is +/- imm8, fold into addr mode. 400 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 401 int RHSC = (int)RHS->getZExtValue(); 402 if ((RHSC >= 0 && RHSC < 256) || 403 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 404 Base = N.getOperand(0); 405 if (Base.getOpcode() == ISD::FrameIndex) { 406 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 407 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 408 } 409 Offset = CurDAG->getRegister(0, MVT::i32); 410 411 ARM_AM::AddrOpc AddSub = ARM_AM::add; 412 if (RHSC < 0) { 413 AddSub = ARM_AM::sub; 414 RHSC = - RHSC; 415 } 416 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32); 417 return true; 418 } 419 } 420 421 Base = N.getOperand(0); 422 Offset = N.getOperand(1); 423 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32); 424 return true; 425} 426 427bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N, 428 SDValue &Offset, SDValue &Opc) { 429 unsigned Opcode = Op->getOpcode(); 430 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 431 ? cast<LoadSDNode>(Op)->getAddressingMode() 432 : cast<StoreSDNode>(Op)->getAddressingMode(); 433 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 434 ? ARM_AM::add : ARM_AM::sub; 435 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 436 int Val = (int)C->getZExtValue(); 437 if (Val >= 0 && Val < 256) { 438 Offset = CurDAG->getRegister(0, MVT::i32); 439 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32); 440 return true; 441 } 442 } 443 444 Offset = N; 445 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32); 446 return true; 447} 448 449bool ARMDAGToDAGISel::SelectAddrMode4(SDNode *Op, SDValue N, 450 SDValue &Addr, SDValue &Mode) { 451 Addr = N; 452 Mode = CurDAG->getTargetConstant(0, MVT::i32); 453 return true; 454} 455 456bool ARMDAGToDAGISel::SelectAddrMode5(SDNode *Op, SDValue N, 457 SDValue &Base, SDValue &Offset) { 458 if (N.getOpcode() != ISD::ADD) { 459 Base = N; 460 if (N.getOpcode() == ISD::FrameIndex) { 461 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 462 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 463 } else if (N.getOpcode() == ARMISD::Wrapper && 464 !(Subtarget->useMovt() && 465 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 466 Base = N.getOperand(0); 467 } 468 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 469 MVT::i32); 470 return true; 471 } 472 473 // If the RHS is +/- imm8, fold into addr mode. 474 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 475 int RHSC = (int)RHS->getZExtValue(); 476 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied by 4. 477 RHSC >>= 2; 478 if ((RHSC >= 0 && RHSC < 256) || 479 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 480 Base = N.getOperand(0); 481 if (Base.getOpcode() == ISD::FrameIndex) { 482 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 483 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 484 } 485 486 ARM_AM::AddrOpc AddSub = ARM_AM::add; 487 if (RHSC < 0) { 488 AddSub = ARM_AM::sub; 489 RHSC = - RHSC; 490 } 491 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC), 492 MVT::i32); 493 return true; 494 } 495 } 496 } 497 498 Base = N; 499 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 500 MVT::i32); 501 return true; 502} 503 504bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Op, SDValue N, 505 SDValue &Addr, SDValue &Align) { 506 Addr = N; 507 // Default to no alignment. 508 Align = CurDAG->getTargetConstant(0, MVT::i32); 509 return true; 510} 511 512bool ARMDAGToDAGISel::SelectAddrModePC(SDNode *Op, SDValue N, 513 SDValue &Offset, SDValue &Label) { 514 if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { 515 Offset = N.getOperand(0); 516 SDValue N1 = N.getOperand(1); 517 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(), 518 MVT::i32); 519 return true; 520 } 521 return false; 522} 523 524bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDNode *Op, SDValue N, 525 SDValue &Base, SDValue &Offset){ 526 // FIXME dl should come from the parent load or store, not the address 527 DebugLoc dl = Op->getDebugLoc(); 528 if (N.getOpcode() != ISD::ADD) { 529 ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N); 530 if (!NC || NC->getZExtValue() != 0) 531 return false; 532 533 Base = Offset = N; 534 return true; 535 } 536 537 Base = N.getOperand(0); 538 Offset = N.getOperand(1); 539 return true; 540} 541 542bool 543ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDNode *Op, SDValue N, 544 unsigned Scale, SDValue &Base, 545 SDValue &OffImm, SDValue &Offset) { 546 if (Scale == 4) { 547 SDValue TmpBase, TmpOffImm; 548 if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm)) 549 return false; // We want to select tLDRspi / tSTRspi instead. 550 if (N.getOpcode() == ARMISD::Wrapper && 551 N.getOperand(0).getOpcode() == ISD::TargetConstantPool) 552 return false; // We want to select tLDRpci instead. 553 } 554 555 if (N.getOpcode() != ISD::ADD) { 556 if (N.getOpcode() == ARMISD::Wrapper && 557 !(Subtarget->useMovt() && 558 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 559 Base = N.getOperand(0); 560 } else 561 Base = N; 562 563 Offset = CurDAG->getRegister(0, MVT::i32); 564 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 565 return true; 566 } 567 568 // Thumb does not have [sp, r] address mode. 569 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 570 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1)); 571 if ((LHSR && LHSR->getReg() == ARM::SP) || 572 (RHSR && RHSR->getReg() == ARM::SP)) { 573 Base = N; 574 Offset = CurDAG->getRegister(0, MVT::i32); 575 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 576 return true; 577 } 578 579 // If the RHS is + imm5 * scale, fold into addr mode. 580 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 581 int RHSC = (int)RHS->getZExtValue(); 582 if ((RHSC & (Scale-1)) == 0) { // The constant is implicitly multiplied. 583 RHSC /= Scale; 584 if (RHSC >= 0 && RHSC < 32) { 585 Base = N.getOperand(0); 586 Offset = CurDAG->getRegister(0, MVT::i32); 587 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 588 return true; 589 } 590 } 591 } 592 593 Base = N.getOperand(0); 594 Offset = N.getOperand(1); 595 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 596 return true; 597} 598 599bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDNode *Op, SDValue N, 600 SDValue &Base, SDValue &OffImm, 601 SDValue &Offset) { 602 return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset); 603} 604 605bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDNode *Op, SDValue N, 606 SDValue &Base, SDValue &OffImm, 607 SDValue &Offset) { 608 return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset); 609} 610 611bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDNode *Op, SDValue N, 612 SDValue &Base, SDValue &OffImm, 613 SDValue &Offset) { 614 return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset); 615} 616 617bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDNode *Op, SDValue N, 618 SDValue &Base, SDValue &OffImm) { 619 if (N.getOpcode() == ISD::FrameIndex) { 620 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 621 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 622 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 623 return true; 624 } 625 626 if (N.getOpcode() != ISD::ADD) 627 return false; 628 629 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 630 if (N.getOperand(0).getOpcode() == ISD::FrameIndex || 631 (LHSR && LHSR->getReg() == ARM::SP)) { 632 // If the RHS is + imm8 * scale, fold into addr mode. 633 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 634 int RHSC = (int)RHS->getZExtValue(); 635 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied. 636 RHSC >>= 2; 637 if (RHSC >= 0 && RHSC < 256) { 638 Base = N.getOperand(0); 639 if (Base.getOpcode() == ISD::FrameIndex) { 640 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 641 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 642 } 643 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 644 return true; 645 } 646 } 647 } 648 } 649 650 return false; 651} 652 653bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDNode *Op, SDValue N, 654 SDValue &BaseReg, 655 SDValue &Opc) { 656 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 657 658 // Don't match base register only case. That is matched to a separate 659 // lower complexity pattern with explicit register operand. 660 if (ShOpcVal == ARM_AM::no_shift) return false; 661 662 BaseReg = N.getOperand(0); 663 unsigned ShImmVal = 0; 664 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 665 ShImmVal = RHS->getZExtValue() & 31; 666 Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal)); 667 return true; 668 } 669 670 return false; 671} 672 673bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDNode *Op, SDValue N, 674 SDValue &Base, SDValue &OffImm) { 675 // Match simple R + imm12 operands. 676 677 // Base only. 678 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 679 if (N.getOpcode() == ISD::FrameIndex) { 680 // Match frame index... 681 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 682 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 683 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 684 return true; 685 } else if (N.getOpcode() == ARMISD::Wrapper && 686 !(Subtarget->useMovt() && 687 N.getOperand(0).getOpcode() == ISD::TargetGlobalAddress)) { 688 Base = N.getOperand(0); 689 if (Base.getOpcode() == ISD::TargetConstantPool) 690 return false; // We want to select t2LDRpci instead. 691 } else 692 Base = N; 693 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 694 return true; 695 } 696 697 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 698 if (SelectT2AddrModeImm8(Op, N, Base, OffImm)) 699 // Let t2LDRi8 handle (R - imm8). 700 return false; 701 702 int RHSC = (int)RHS->getZExtValue(); 703 if (N.getOpcode() == ISD::SUB) 704 RHSC = -RHSC; 705 706 if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits (unsigned) 707 Base = N.getOperand(0); 708 if (Base.getOpcode() == ISD::FrameIndex) { 709 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 710 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 711 } 712 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 713 return true; 714 } 715 } 716 717 // Base only. 718 Base = N; 719 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 720 return true; 721} 722 723bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDNode *Op, SDValue N, 724 SDValue &Base, SDValue &OffImm) { 725 // Match simple R - imm8 operands. 726 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::SUB) { 727 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 728 int RHSC = (int)RHS->getSExtValue(); 729 if (N.getOpcode() == ISD::SUB) 730 RHSC = -RHSC; 731 732 if ((RHSC >= -255) && (RHSC < 0)) { // 8 bits (always negative) 733 Base = N.getOperand(0); 734 if (Base.getOpcode() == ISD::FrameIndex) { 735 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 736 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 737 } 738 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 739 return true; 740 } 741 } 742 } 743 744 return false; 745} 746 747bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, 748 SDValue &OffImm){ 749 unsigned Opcode = Op->getOpcode(); 750 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 751 ? cast<LoadSDNode>(Op)->getAddressingMode() 752 : cast<StoreSDNode>(Op)->getAddressingMode(); 753 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N)) { 754 int RHSC = (int)RHS->getZExtValue(); 755 if (RHSC >= 0 && RHSC < 0x100) { // 8 bits. 756 OffImm = ((AM == ISD::PRE_INC) || (AM == ISD::POST_INC)) 757 ? CurDAG->getTargetConstant(RHSC, MVT::i32) 758 : CurDAG->getTargetConstant(-RHSC, MVT::i32); 759 return true; 760 } 761 } 762 763 return false; 764} 765 766bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDNode *Op, SDValue N, 767 SDValue &Base, SDValue &OffImm) { 768 if (N.getOpcode() == ISD::ADD) { 769 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 770 int RHSC = (int)RHS->getZExtValue(); 771 if (((RHSC & 0x3) == 0) && 772 ((RHSC >= 0 && RHSC < 0x400) || (RHSC < 0 && RHSC > -0x400))) { // 8 bits. 773 Base = N.getOperand(0); 774 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 775 return true; 776 } 777 } 778 } else if (N.getOpcode() == ISD::SUB) { 779 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 780 int RHSC = (int)RHS->getZExtValue(); 781 if (((RHSC & 0x3) == 0) && (RHSC >= 0 && RHSC < 0x400)) { // 8 bits. 782 Base = N.getOperand(0); 783 OffImm = CurDAG->getTargetConstant(-RHSC, MVT::i32); 784 return true; 785 } 786 } 787 } 788 789 return false; 790} 791 792bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDNode *Op, SDValue N, 793 SDValue &Base, 794 SDValue &OffReg, SDValue &ShImm) { 795 // (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12. 796 if (N.getOpcode() != ISD::ADD) 797 return false; 798 799 // Leave (R + imm12) for t2LDRi12, (R - imm8) for t2LDRi8. 800 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 801 int RHSC = (int)RHS->getZExtValue(); 802 if (RHSC >= 0 && RHSC < 0x1000) // 12 bits (unsigned) 803 return false; 804 else if (RHSC < 0 && RHSC >= -255) // 8 bits 805 return false; 806 } 807 808 // Look for (R + R) or (R + (R << [1,2,3])). 809 unsigned ShAmt = 0; 810 Base = N.getOperand(0); 811 OffReg = N.getOperand(1); 812 813 // Swap if it is ((R << c) + R). 814 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg); 815 if (ShOpcVal != ARM_AM::lsl) { 816 ShOpcVal = ARM_AM::getShiftOpcForNode(Base); 817 if (ShOpcVal == ARM_AM::lsl) 818 std::swap(Base, OffReg); 819 } 820 821 if (ShOpcVal == ARM_AM::lsl) { 822 // Check to see if the RHS of the shift is a constant, if not, we can't fold 823 // it. 824 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(OffReg.getOperand(1))) { 825 ShAmt = Sh->getZExtValue(); 826 if (ShAmt >= 4) { 827 ShAmt = 0; 828 ShOpcVal = ARM_AM::no_shift; 829 } else 830 OffReg = OffReg.getOperand(0); 831 } else { 832 ShOpcVal = ARM_AM::no_shift; 833 } 834 } 835 836 ShImm = CurDAG->getTargetConstant(ShAmt, MVT::i32); 837 838 return true; 839} 840 841//===--------------------------------------------------------------------===// 842 843/// getAL - Returns a ARMCC::AL immediate node. 844static inline SDValue getAL(SelectionDAG *CurDAG) { 845 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32); 846} 847 848SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDNode *N) { 849 LoadSDNode *LD = cast<LoadSDNode>(N); 850 ISD::MemIndexedMode AM = LD->getAddressingMode(); 851 if (AM == ISD::UNINDEXED) 852 return NULL; 853 854 EVT LoadedVT = LD->getMemoryVT(); 855 SDValue Offset, AMOpc; 856 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 857 unsigned Opcode = 0; 858 bool Match = false; 859 if (LoadedVT == MVT::i32 && 860 SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { 861 Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST; 862 Match = true; 863 } else if (LoadedVT == MVT::i16 && 864 SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 865 Match = true; 866 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) 867 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) 868 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); 869 } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) { 870 if (LD->getExtensionType() == ISD::SEXTLOAD) { 871 if (SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { 872 Match = true; 873 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; 874 } 875 } else { 876 if (SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { 877 Match = true; 878 Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST; 879 } 880 } 881 } 882 883 if (Match) { 884 SDValue Chain = LD->getChain(); 885 SDValue Base = LD->getBasePtr(); 886 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), 887 CurDAG->getRegister(0, MVT::i32), Chain }; 888 return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32, 889 MVT::Other, Ops, 6); 890 } 891 892 return NULL; 893} 894 895SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) { 896 LoadSDNode *LD = cast<LoadSDNode>(N); 897 ISD::MemIndexedMode AM = LD->getAddressingMode(); 898 if (AM == ISD::UNINDEXED) 899 return NULL; 900 901 EVT LoadedVT = LD->getMemoryVT(); 902 bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD; 903 SDValue Offset; 904 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 905 unsigned Opcode = 0; 906 bool Match = false; 907 if (SelectT2AddrModeImm8Offset(N, LD->getOffset(), Offset)) { 908 switch (LoadedVT.getSimpleVT().SimpleTy) { 909 case MVT::i32: 910 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST; 911 break; 912 case MVT::i16: 913 if (isSExtLd) 914 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST; 915 else 916 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST; 917 break; 918 case MVT::i8: 919 case MVT::i1: 920 if (isSExtLd) 921 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST; 922 else 923 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST; 924 break; 925 default: 926 return NULL; 927 } 928 Match = true; 929 } 930 931 if (Match) { 932 SDValue Chain = LD->getChain(); 933 SDValue Base = LD->getBasePtr(); 934 SDValue Ops[]= { Base, Offset, getAL(CurDAG), 935 CurDAG->getRegister(0, MVT::i32), Chain }; 936 return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32, 937 MVT::Other, Ops, 5); 938 } 939 940 return NULL; 941} 942 943/// PairDRegs - Insert a pair of double registers into an implicit def to 944/// form a quad register. 945SDNode *ARMDAGToDAGISel::PairDRegs(EVT VT, SDValue V0, SDValue V1) { 946 DebugLoc dl = V0.getNode()->getDebugLoc(); 947 SDValue SubReg0 = CurDAG->getTargetConstant(ARM::DSUBREG_0, MVT::i32); 948 SDValue SubReg1 = CurDAG->getTargetConstant(ARM::DSUBREG_1, MVT::i32); 949 if (UseRegSeq) { 950 const SDValue Ops[] = { V0, SubReg0, V1, SubReg1 }; 951 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops, 4); 952 } 953 SDValue Undef = 954 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0); 955 SDNode *Pair = CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, 956 VT, Undef, V0, SubReg0); 957 return CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, 958 VT, SDValue(Pair, 0), V1, SubReg1); 959} 960 961/// GetNEONSubregVT - Given a type for a 128-bit NEON vector, return the type 962/// for a 64-bit subregister of the vector. 963static EVT GetNEONSubregVT(EVT VT) { 964 switch (VT.getSimpleVT().SimpleTy) { 965 default: llvm_unreachable("unhandled NEON type"); 966 case MVT::v16i8: return MVT::v8i8; 967 case MVT::v8i16: return MVT::v4i16; 968 case MVT::v4f32: return MVT::v2f32; 969 case MVT::v4i32: return MVT::v2i32; 970 case MVT::v2i64: return MVT::v1i64; 971 } 972} 973 974SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs, 975 unsigned *DOpcodes, unsigned *QOpcodes0, 976 unsigned *QOpcodes1) { 977 assert(NumVecs >= 1 && NumVecs <= 4 && "VLD NumVecs out-of-range"); 978 DebugLoc dl = N->getDebugLoc(); 979 980 SDValue MemAddr, Align; 981 if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align)) 982 return NULL; 983 984 SDValue Chain = N->getOperand(0); 985 EVT VT = N->getValueType(0); 986 bool is64BitVector = VT.is64BitVector(); 987 988 unsigned OpcodeIndex; 989 switch (VT.getSimpleVT().SimpleTy) { 990 default: llvm_unreachable("unhandled vld type"); 991 // Double-register operations: 992 case MVT::v8i8: OpcodeIndex = 0; break; 993 case MVT::v4i16: OpcodeIndex = 1; break; 994 case MVT::v2f32: 995 case MVT::v2i32: OpcodeIndex = 2; break; 996 case MVT::v1i64: OpcodeIndex = 3; break; 997 // Quad-register operations: 998 case MVT::v16i8: OpcodeIndex = 0; break; 999 case MVT::v8i16: OpcodeIndex = 1; break; 1000 case MVT::v4f32: 1001 case MVT::v4i32: OpcodeIndex = 2; break; 1002 case MVT::v2i64: OpcodeIndex = 3; 1003 assert(NumVecs == 1 && "v2i64 type only supported for VLD1"); 1004 break; 1005 } 1006 1007 SDValue Pred = getAL(CurDAG); 1008 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1009 if (is64BitVector) { 1010 unsigned Opc = DOpcodes[OpcodeIndex]; 1011 const SDValue Ops[] = { MemAddr, Align, Pred, Reg0, Chain }; 1012 std::vector<EVT> ResTys(NumVecs, VT); 1013 ResTys.push_back(MVT::Other); 1014 return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); 1015 } 1016 1017 EVT RegVT = GetNEONSubregVT(VT); 1018 if (NumVecs <= 2) { 1019 // Quad registers are directly supported for VLD1 and VLD2, 1020 // loading pairs of D regs. 1021 unsigned Opc = QOpcodes0[OpcodeIndex]; 1022 const SDValue Ops[] = { MemAddr, Align, Pred, Reg0, Chain }; 1023 std::vector<EVT> ResTys(2 * NumVecs, RegVT); 1024 ResTys.push_back(MVT::Other); 1025 SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); 1026 Chain = SDValue(VLd, 2 * NumVecs); 1027 1028 // Combine the even and odd subregs to produce the result. 1029 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1030 SDNode *Q = PairDRegs(VT, SDValue(VLd, 2*Vec), SDValue(VLd, 2*Vec+1)); 1031 ReplaceUses(SDValue(N, Vec), SDValue(Q, 0)); 1032 } 1033 } else { 1034 // Otherwise, quad registers are loaded with two separate instructions, 1035 // where one loads the even registers and the other loads the odd registers. 1036 1037 std::vector<EVT> ResTys(NumVecs, RegVT); 1038 ResTys.push_back(MemAddr.getValueType()); 1039 ResTys.push_back(MVT::Other); 1040 1041 // Load the even subregs. 1042 unsigned Opc = QOpcodes0[OpcodeIndex]; 1043 const SDValue OpsA[] = { MemAddr, Align, Reg0, Pred, Reg0, Chain }; 1044 SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 6); 1045 Chain = SDValue(VLdA, NumVecs+1); 1046 1047 // Load the odd subregs. 1048 Opc = QOpcodes1[OpcodeIndex]; 1049 const SDValue OpsB[] = { SDValue(VLdA, NumVecs), 1050 Align, Reg0, Pred, Reg0, Chain }; 1051 SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 6); 1052 Chain = SDValue(VLdB, NumVecs+1); 1053 1054 // Combine the even and odd subregs to produce the result. 1055 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1056 SDNode *Q = PairDRegs(VT, SDValue(VLdA, Vec), SDValue(VLdB, Vec)); 1057 ReplaceUses(SDValue(N, Vec), SDValue(Q, 0)); 1058 } 1059 } 1060 ReplaceUses(SDValue(N, NumVecs), Chain); 1061 return NULL; 1062} 1063 1064SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs, 1065 unsigned *DOpcodes, unsigned *QOpcodes0, 1066 unsigned *QOpcodes1) { 1067 assert(NumVecs >=1 && NumVecs <= 4 && "VST NumVecs out-of-range"); 1068 DebugLoc dl = N->getDebugLoc(); 1069 1070 SDValue MemAddr, Align; 1071 if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align)) 1072 return NULL; 1073 1074 SDValue Chain = N->getOperand(0); 1075 EVT VT = N->getOperand(3).getValueType(); 1076 bool is64BitVector = VT.is64BitVector(); 1077 1078 unsigned OpcodeIndex; 1079 switch (VT.getSimpleVT().SimpleTy) { 1080 default: llvm_unreachable("unhandled vst type"); 1081 // Double-register operations: 1082 case MVT::v8i8: OpcodeIndex = 0; break; 1083 case MVT::v4i16: OpcodeIndex = 1; break; 1084 case MVT::v2f32: 1085 case MVT::v2i32: OpcodeIndex = 2; break; 1086 case MVT::v1i64: OpcodeIndex = 3; break; 1087 // Quad-register operations: 1088 case MVT::v16i8: OpcodeIndex = 0; break; 1089 case MVT::v8i16: OpcodeIndex = 1; break; 1090 case MVT::v4f32: 1091 case MVT::v4i32: OpcodeIndex = 2; break; 1092 case MVT::v2i64: OpcodeIndex = 3; 1093 assert(NumVecs == 1 && "v2i64 type only supported for VST1"); 1094 break; 1095 } 1096 1097 SDValue Pred = getAL(CurDAG); 1098 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1099 1100 SmallVector<SDValue, 10> Ops; 1101 Ops.push_back(MemAddr); 1102 Ops.push_back(Align); 1103 1104 if (is64BitVector) { 1105 unsigned Opc = DOpcodes[OpcodeIndex]; 1106 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1107 Ops.push_back(N->getOperand(Vec+3)); 1108 Ops.push_back(Pred); 1109 Ops.push_back(Reg0); // predicate register 1110 Ops.push_back(Chain); 1111 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+5); 1112 } 1113 1114 EVT RegVT = GetNEONSubregVT(VT); 1115 if (NumVecs <= 2) { 1116 // Quad registers are directly supported for VST1 and VST2, 1117 // storing pairs of D regs. 1118 unsigned Opc = QOpcodes0[OpcodeIndex]; 1119 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1120 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT, 1121 N->getOperand(Vec+3))); 1122 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, 1123 N->getOperand(Vec+3))); 1124 } 1125 Ops.push_back(Pred); 1126 Ops.push_back(Reg0); // predicate register 1127 Ops.push_back(Chain); 1128 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 1129 5 + 2 * NumVecs); 1130 } 1131 1132 // Otherwise, quad registers are stored with two separate instructions, 1133 // where one stores the even registers and the other stores the odd registers. 1134 1135 Ops.push_back(Reg0); // post-access address offset 1136 1137 // Store the even subregs. 1138 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1139 Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT, 1140 N->getOperand(Vec+3))); 1141 Ops.push_back(Pred); 1142 Ops.push_back(Reg0); // predicate register 1143 Ops.push_back(Chain); 1144 unsigned Opc = QOpcodes0[OpcodeIndex]; 1145 SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(), 1146 MVT::Other, Ops.data(), NumVecs+6); 1147 Chain = SDValue(VStA, 1); 1148 1149 // Store the odd subregs. 1150 Ops[0] = SDValue(VStA, 0); // MemAddr 1151 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1152 Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, 1153 N->getOperand(Vec+3)); 1154 Ops[NumVecs+5] = Chain; 1155 Opc = QOpcodes1[OpcodeIndex]; 1156 SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(), 1157 MVT::Other, Ops.data(), NumVecs+6); 1158 Chain = SDValue(VStB, 1); 1159 ReplaceUses(SDValue(N, 0), Chain); 1160 return NULL; 1161} 1162 1163SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad, 1164 unsigned NumVecs, unsigned *DOpcodes, 1165 unsigned *QOpcodes0, 1166 unsigned *QOpcodes1) { 1167 assert(NumVecs >=2 && NumVecs <= 4 && "VLDSTLane NumVecs out-of-range"); 1168 DebugLoc dl = N->getDebugLoc(); 1169 1170 SDValue MemAddr, Align; 1171 if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align)) 1172 return NULL; 1173 1174 SDValue Chain = N->getOperand(0); 1175 unsigned Lane = 1176 cast<ConstantSDNode>(N->getOperand(NumVecs+3))->getZExtValue(); 1177 EVT VT = IsLoad ? N->getValueType(0) : N->getOperand(3).getValueType(); 1178 bool is64BitVector = VT.is64BitVector(); 1179 1180 // Quad registers are handled by load/store of subregs. Find the subreg info. 1181 unsigned NumElts = 0; 1182 int SubregIdx = 0; 1183 EVT RegVT = VT; 1184 if (!is64BitVector) { 1185 RegVT = GetNEONSubregVT(VT); 1186 NumElts = RegVT.getVectorNumElements(); 1187 SubregIdx = (Lane < NumElts) ? ARM::DSUBREG_0 : ARM::DSUBREG_1; 1188 } 1189 1190 unsigned OpcodeIndex; 1191 switch (VT.getSimpleVT().SimpleTy) { 1192 default: llvm_unreachable("unhandled vld/vst lane type"); 1193 // Double-register operations: 1194 case MVT::v8i8: OpcodeIndex = 0; break; 1195 case MVT::v4i16: OpcodeIndex = 1; break; 1196 case MVT::v2f32: 1197 case MVT::v2i32: OpcodeIndex = 2; break; 1198 // Quad-register operations: 1199 case MVT::v8i16: OpcodeIndex = 0; break; 1200 case MVT::v4f32: 1201 case MVT::v4i32: OpcodeIndex = 1; break; 1202 } 1203 1204 SDValue Pred = getAL(CurDAG); 1205 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1206 1207 SmallVector<SDValue, 10> Ops; 1208 Ops.push_back(MemAddr); 1209 Ops.push_back(Align); 1210 1211 unsigned Opc = 0; 1212 if (is64BitVector) { 1213 Opc = DOpcodes[OpcodeIndex]; 1214 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1215 Ops.push_back(N->getOperand(Vec+3)); 1216 } else { 1217 // Check if this is loading the even or odd subreg of a Q register. 1218 if (Lane < NumElts) { 1219 Opc = QOpcodes0[OpcodeIndex]; 1220 } else { 1221 Lane -= NumElts; 1222 Opc = QOpcodes1[OpcodeIndex]; 1223 } 1224 // Extract the subregs of the input vector. 1225 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) 1226 Ops.push_back(CurDAG->getTargetExtractSubreg(SubregIdx, dl, RegVT, 1227 N->getOperand(Vec+3))); 1228 } 1229 Ops.push_back(getI32Imm(Lane)); 1230 Ops.push_back(Pred); 1231 Ops.push_back(Reg0); 1232 Ops.push_back(Chain); 1233 1234 if (!IsLoad) 1235 return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+6); 1236 1237 std::vector<EVT> ResTys(NumVecs, RegVT); 1238 ResTys.push_back(MVT::Other); 1239 SDNode *VLdLn = 1240 CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+6); 1241 // For a 64-bit vector load to D registers, nothing more needs to be done. 1242 if (is64BitVector) 1243 return VLdLn; 1244 1245 // For 128-bit vectors, take the 64-bit results of the load and insert them 1246 // as subregs into the result. 1247 for (unsigned Vec = 0; Vec < NumVecs; ++Vec) { 1248 SDValue QuadVec = CurDAG->getTargetInsertSubreg(SubregIdx, dl, VT, 1249 N->getOperand(Vec+3), 1250 SDValue(VLdLn, Vec)); 1251 ReplaceUses(SDValue(N, Vec), QuadVec); 1252 } 1253 1254 Chain = SDValue(VLdLn, NumVecs); 1255 ReplaceUses(SDValue(N, NumVecs), Chain); 1256 return NULL; 1257} 1258 1259SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N, 1260 bool isSigned) { 1261 if (!Subtarget->hasV6T2Ops()) 1262 return NULL; 1263 1264 unsigned Opc = isSigned ? (Subtarget->isThumb() ? ARM::t2SBFX : ARM::SBFX) 1265 : (Subtarget->isThumb() ? ARM::t2UBFX : ARM::UBFX); 1266 1267 1268 // For unsigned extracts, check for a shift right and mask 1269 unsigned And_imm = 0; 1270 if (N->getOpcode() == ISD::AND) { 1271 if (isOpcWithIntImmediate(N, ISD::AND, And_imm)) { 1272 1273 // The immediate is a mask of the low bits iff imm & (imm+1) == 0 1274 if (And_imm & (And_imm + 1)) 1275 return NULL; 1276 1277 unsigned Srl_imm = 0; 1278 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRL, 1279 Srl_imm)) { 1280 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 1281 1282 unsigned Width = CountTrailingOnes_32(And_imm); 1283 unsigned LSB = Srl_imm; 1284 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1285 SDValue Ops[] = { N->getOperand(0).getOperand(0), 1286 CurDAG->getTargetConstant(LSB, MVT::i32), 1287 CurDAG->getTargetConstant(Width, MVT::i32), 1288 getAL(CurDAG), Reg0 }; 1289 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); 1290 } 1291 } 1292 return NULL; 1293 } 1294 1295 // Otherwise, we're looking for a shift of a shift 1296 unsigned Shl_imm = 0; 1297 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, Shl_imm)) { 1298 assert(Shl_imm > 0 && Shl_imm < 32 && "bad amount in shift node!"); 1299 unsigned Srl_imm = 0; 1300 if (isInt32Immediate(N->getOperand(1), Srl_imm)) { 1301 assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); 1302 unsigned Width = 32 - Srl_imm; 1303 int LSB = Srl_imm - Shl_imm; 1304 if (LSB < 0) 1305 return NULL; 1306 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1307 SDValue Ops[] = { N->getOperand(0).getOperand(0), 1308 CurDAG->getTargetConstant(LSB, MVT::i32), 1309 CurDAG->getTargetConstant(Width, MVT::i32), 1310 getAL(CurDAG), Reg0 }; 1311 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); 1312 } 1313 } 1314 return NULL; 1315} 1316 1317SDNode *ARMDAGToDAGISel:: 1318SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1319 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1320 SDValue CPTmp0; 1321 SDValue CPTmp1; 1322 if (SelectT2ShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1)) { 1323 unsigned SOVal = cast<ConstantSDNode>(CPTmp1)->getZExtValue(); 1324 unsigned SOShOp = ARM_AM::getSORegShOp(SOVal); 1325 unsigned Opc = 0; 1326 switch (SOShOp) { 1327 case ARM_AM::lsl: Opc = ARM::t2MOVCClsl; break; 1328 case ARM_AM::lsr: Opc = ARM::t2MOVCClsr; break; 1329 case ARM_AM::asr: Opc = ARM::t2MOVCCasr; break; 1330 case ARM_AM::ror: Opc = ARM::t2MOVCCror; break; 1331 default: 1332 llvm_unreachable("Unknown so_reg opcode!"); 1333 break; 1334 } 1335 SDValue SOShImm = 1336 CurDAG->getTargetConstant(ARM_AM::getSORegOffset(SOVal), MVT::i32); 1337 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1338 SDValue Ops[] = { FalseVal, CPTmp0, SOShImm, CC, CCR, InFlag }; 1339 return CurDAG->SelectNodeTo(N, Opc, MVT::i32,Ops, 6); 1340 } 1341 return 0; 1342} 1343 1344SDNode *ARMDAGToDAGISel:: 1345SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1346 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1347 SDValue CPTmp0; 1348 SDValue CPTmp1; 1349 SDValue CPTmp2; 1350 if (SelectShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1, CPTmp2)) { 1351 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1352 SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag }; 1353 return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7); 1354 } 1355 return 0; 1356} 1357 1358SDNode *ARMDAGToDAGISel:: 1359SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1360 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1361 ConstantSDNode *T = dyn_cast<ConstantSDNode>(TrueVal); 1362 if (!T) 1363 return 0; 1364 1365 if (Predicate_t2_so_imm(TrueVal.getNode())) { 1366 SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32); 1367 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1368 SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag }; 1369 return CurDAG->SelectNodeTo(N, 1370 ARM::t2MOVCCi, MVT::i32, Ops, 5); 1371 } 1372 return 0; 1373} 1374 1375SDNode *ARMDAGToDAGISel:: 1376SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 1377 ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { 1378 ConstantSDNode *T = dyn_cast<ConstantSDNode>(TrueVal); 1379 if (!T) 1380 return 0; 1381 1382 if (Predicate_so_imm(TrueVal.getNode())) { 1383 SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32); 1384 SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); 1385 SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag }; 1386 return CurDAG->SelectNodeTo(N, 1387 ARM::MOVCCi, MVT::i32, Ops, 5); 1388 } 1389 return 0; 1390} 1391 1392SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDNode *N) { 1393 EVT VT = N->getValueType(0); 1394 SDValue FalseVal = N->getOperand(0); 1395 SDValue TrueVal = N->getOperand(1); 1396 SDValue CC = N->getOperand(2); 1397 SDValue CCR = N->getOperand(3); 1398 SDValue InFlag = N->getOperand(4); 1399 assert(CC.getOpcode() == ISD::Constant); 1400 assert(CCR.getOpcode() == ISD::Register); 1401 ARMCC::CondCodes CCVal = 1402 (ARMCC::CondCodes)cast<ConstantSDNode>(CC)->getZExtValue(); 1403 1404 if (!Subtarget->isThumb1Only() && VT == MVT::i32) { 1405 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1406 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1407 // Pattern complexity = 18 cost = 1 size = 0 1408 SDValue CPTmp0; 1409 SDValue CPTmp1; 1410 SDValue CPTmp2; 1411 if (Subtarget->isThumb()) { 1412 SDNode *Res = SelectT2CMOVShiftOp(N, FalseVal, TrueVal, 1413 CCVal, CCR, InFlag); 1414 if (!Res) 1415 Res = SelectT2CMOVShiftOp(N, TrueVal, FalseVal, 1416 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1417 if (Res) 1418 return Res; 1419 } else { 1420 SDNode *Res = SelectARMCMOVShiftOp(N, FalseVal, TrueVal, 1421 CCVal, CCR, InFlag); 1422 if (!Res) 1423 Res = SelectARMCMOVShiftOp(N, TrueVal, FalseVal, 1424 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1425 if (Res) 1426 return Res; 1427 } 1428 1429 // Pattern: (ARMcmov:i32 GPR:i32:$false, 1430 // (imm:i32)<<P:Predicate_so_imm>>:$true, 1431 // (imm:i32):$cc) 1432 // Emits: (MOVCCi:i32 GPR:i32:$false, 1433 // (so_imm:i32 (imm:i32):$true), (imm:i32):$cc) 1434 // Pattern complexity = 10 cost = 1 size = 0 1435 if (Subtarget->isThumb()) { 1436 SDNode *Res = SelectT2CMOVSoImmOp(N, FalseVal, TrueVal, 1437 CCVal, CCR, InFlag); 1438 if (!Res) 1439 Res = SelectT2CMOVSoImmOp(N, TrueVal, FalseVal, 1440 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1441 if (Res) 1442 return Res; 1443 } else { 1444 SDNode *Res = SelectARMCMOVSoImmOp(N, FalseVal, TrueVal, 1445 CCVal, CCR, InFlag); 1446 if (!Res) 1447 Res = SelectARMCMOVSoImmOp(N, TrueVal, FalseVal, 1448 ARMCC::getOppositeCondition(CCVal), CCR, InFlag); 1449 if (Res) 1450 return Res; 1451 } 1452 } 1453 1454 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1455 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1456 // Pattern complexity = 6 cost = 1 size = 0 1457 // 1458 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1459 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1460 // Pattern complexity = 6 cost = 11 size = 0 1461 // 1462 // Also FCPYScc and FCPYDcc. 1463 SDValue Tmp2 = CurDAG->getTargetConstant(CCVal, MVT::i32); 1464 SDValue Ops[] = { FalseVal, TrueVal, Tmp2, CCR, InFlag }; 1465 unsigned Opc = 0; 1466 switch (VT.getSimpleVT().SimpleTy) { 1467 default: assert(false && "Illegal conditional move type!"); 1468 break; 1469 case MVT::i32: 1470 Opc = Subtarget->isThumb() 1471 ? (Subtarget->hasThumb2() ? ARM::t2MOVCCr : ARM::tMOVCCr_pseudo) 1472 : ARM::MOVCCr; 1473 break; 1474 case MVT::f32: 1475 Opc = ARM::VMOVScc; 1476 break; 1477 case MVT::f64: 1478 Opc = ARM::VMOVDcc; 1479 break; 1480 } 1481 return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5); 1482} 1483 1484SDNode *ARMDAGToDAGISel::Select(SDNode *N) { 1485 DebugLoc dl = N->getDebugLoc(); 1486 1487 if (N->isMachineOpcode()) 1488 return NULL; // Already selected. 1489 1490 switch (N->getOpcode()) { 1491 default: break; 1492 case ISD::Constant: { 1493 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 1494 bool UseCP = true; 1495 if (Subtarget->hasThumb2()) 1496 // Thumb2-aware targets have the MOVT instruction, so all immediates can 1497 // be done with MOV + MOVT, at worst. 1498 UseCP = 0; 1499 else { 1500 if (Subtarget->isThumb()) { 1501 UseCP = (Val > 255 && // MOV 1502 ~Val > 255 && // MOV + MVN 1503 !ARM_AM::isThumbImmShiftedVal(Val)); // MOV + LSL 1504 } else 1505 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV 1506 ARM_AM::getSOImmVal(~Val) == -1 && // MVN 1507 !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs. 1508 } 1509 1510 if (UseCP) { 1511 SDValue CPIdx = 1512 CurDAG->getTargetConstantPool(ConstantInt::get( 1513 Type::getInt32Ty(*CurDAG->getContext()), Val), 1514 TLI.getPointerTy()); 1515 1516 SDNode *ResNode; 1517 if (Subtarget->isThumb1Only()) { 1518 SDValue Pred = getAL(CurDAG); 1519 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1520 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() }; 1521 ResNode = CurDAG->getMachineNode(ARM::tLDRcp, dl, MVT::i32, MVT::Other, 1522 Ops, 4); 1523 } else { 1524 SDValue Ops[] = { 1525 CPIdx, 1526 CurDAG->getRegister(0, MVT::i32), 1527 CurDAG->getTargetConstant(0, MVT::i32), 1528 getAL(CurDAG), 1529 CurDAG->getRegister(0, MVT::i32), 1530 CurDAG->getEntryNode() 1531 }; 1532 ResNode=CurDAG->getMachineNode(ARM::LDRcp, dl, MVT::i32, MVT::Other, 1533 Ops, 6); 1534 } 1535 ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0)); 1536 return NULL; 1537 } 1538 1539 // Other cases are autogenerated. 1540 break; 1541 } 1542 case ISD::FrameIndex: { 1543 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. 1544 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1545 SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 1546 if (Subtarget->isThumb1Only()) { 1547 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI, 1548 CurDAG->getTargetConstant(0, MVT::i32)); 1549 } else { 1550 unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ? 1551 ARM::t2ADDri : ARM::ADDri); 1552 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), 1553 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1554 CurDAG->getRegister(0, MVT::i32) }; 1555 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); 1556 } 1557 } 1558 case ISD::SRL: 1559 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, false)) 1560 return I; 1561 break; 1562 case ISD::SRA: 1563 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, true)) 1564 return I; 1565 break; 1566 case ISD::MUL: 1567 if (Subtarget->isThumb1Only()) 1568 break; 1569 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) { 1570 unsigned RHSV = C->getZExtValue(); 1571 if (!RHSV) break; 1572 if (isPowerOf2_32(RHSV-1)) { // 2^n+1? 1573 unsigned ShImm = Log2_32(RHSV-1); 1574 if (ShImm >= 32) 1575 break; 1576 SDValue V = N->getOperand(0); 1577 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 1578 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); 1579 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1580 if (Subtarget->isThumb()) { 1581 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1582 return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops, 6); 1583 } else { 1584 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1585 return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7); 1586 } 1587 } 1588 if (isPowerOf2_32(RHSV+1)) { // 2^n-1? 1589 unsigned ShImm = Log2_32(RHSV+1); 1590 if (ShImm >= 32) 1591 break; 1592 SDValue V = N->getOperand(0); 1593 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 1594 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); 1595 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 1596 if (Subtarget->isThumb()) { 1597 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0 }; 1598 return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops, 5); 1599 } else { 1600 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1601 return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7); 1602 } 1603 } 1604 } 1605 break; 1606 case ISD::AND: { 1607 // Check for unsigned bitfield extract 1608 if (SDNode *I = SelectV6T2BitfieldExtractOp(N, false)) 1609 return I; 1610 1611 // (and (or x, c2), c1) and top 16-bits of c1 and c2 match, lower 16-bits 1612 // of c1 are 0xffff, and lower 16-bit of c2 are 0. That is, the top 16-bits 1613 // are entirely contributed by c2 and lower 16-bits are entirely contributed 1614 // by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)). 1615 // Select it to: "movt x, ((c1 & 0xffff) >> 16) 1616 EVT VT = N->getValueType(0); 1617 if (VT != MVT::i32) 1618 break; 1619 unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2()) 1620 ? ARM::t2MOVTi16 1621 : (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0); 1622 if (!Opc) 1623 break; 1624 SDValue N0 = N->getOperand(0), N1 = N->getOperand(1); 1625 ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1); 1626 if (!N1C) 1627 break; 1628 if (N0.getOpcode() == ISD::OR && N0.getNode()->hasOneUse()) { 1629 SDValue N2 = N0.getOperand(1); 1630 ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2); 1631 if (!N2C) 1632 break; 1633 unsigned N1CVal = N1C->getZExtValue(); 1634 unsigned N2CVal = N2C->getZExtValue(); 1635 if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) && 1636 (N1CVal & 0xffffU) == 0xffffU && 1637 (N2CVal & 0xffffU) == 0x0U) { 1638 SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16, 1639 MVT::i32); 1640 SDValue Ops[] = { N0.getOperand(0), Imm16, 1641 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; 1642 return CurDAG->getMachineNode(Opc, dl, VT, Ops, 4); 1643 } 1644 } 1645 break; 1646 } 1647 case ARMISD::VMOVRRD: 1648 return CurDAG->getMachineNode(ARM::VMOVRRD, dl, MVT::i32, MVT::i32, 1649 N->getOperand(0), getAL(CurDAG), 1650 CurDAG->getRegister(0, MVT::i32)); 1651 case ISD::UMUL_LOHI: { 1652 if (Subtarget->isThumb1Only()) 1653 break; 1654 if (Subtarget->isThumb()) { 1655 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 1656 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1657 CurDAG->getRegister(0, MVT::i32) }; 1658 return CurDAG->getMachineNode(ARM::t2UMULL, dl, MVT::i32, MVT::i32, Ops,4); 1659 } else { 1660 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 1661 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1662 CurDAG->getRegister(0, MVT::i32) }; 1663 return CurDAG->getMachineNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5); 1664 } 1665 } 1666 case ISD::SMUL_LOHI: { 1667 if (Subtarget->isThumb1Only()) 1668 break; 1669 if (Subtarget->isThumb()) { 1670 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 1671 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; 1672 return CurDAG->getMachineNode(ARM::t2SMULL, dl, MVT::i32, MVT::i32, Ops,4); 1673 } else { 1674 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), 1675 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1676 CurDAG->getRegister(0, MVT::i32) }; 1677 return CurDAG->getMachineNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5); 1678 } 1679 } 1680 case ISD::LOAD: { 1681 SDNode *ResNode = 0; 1682 if (Subtarget->isThumb() && Subtarget->hasThumb2()) 1683 ResNode = SelectT2IndexedLoad(N); 1684 else 1685 ResNode = SelectARMIndexedLoad(N); 1686 if (ResNode) 1687 return ResNode; 1688 1689 // VLDMQ must be custom-selected for "v2f64 load" to set the AM5Opc value. 1690 if (Subtarget->hasVFP2() && 1691 N->getValueType(0).getSimpleVT().SimpleTy == MVT::v2f64) { 1692 SDValue Chain = N->getOperand(0); 1693 SDValue AM5Opc = 1694 CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::ia, 4), MVT::i32); 1695 SDValue Pred = getAL(CurDAG); 1696 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1697 SDValue Ops[] = { N->getOperand(1), AM5Opc, Pred, PredReg, Chain }; 1698 return CurDAG->getMachineNode(ARM::VLDMQ, dl, MVT::v2f64, MVT::Other, 1699 Ops, 5); 1700 } 1701 // Other cases are autogenerated. 1702 break; 1703 } 1704 case ISD::STORE: { 1705 // VSTMQ must be custom-selected for "v2f64 store" to set the AM5Opc value. 1706 if (Subtarget->hasVFP2() && 1707 N->getOperand(1).getValueType().getSimpleVT().SimpleTy == MVT::v2f64) { 1708 SDValue Chain = N->getOperand(0); 1709 SDValue AM5Opc = 1710 CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::ia, 4), MVT::i32); 1711 SDValue Pred = getAL(CurDAG); 1712 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1713 SDValue Ops[] = { N->getOperand(1), N->getOperand(2), 1714 AM5Opc, Pred, PredReg, Chain }; 1715 return CurDAG->getMachineNode(ARM::VSTMQ, dl, MVT::Other, Ops, 6); 1716 } 1717 // Other cases are autogenerated. 1718 break; 1719 } 1720 case ARMISD::BRCOND: { 1721 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1722 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc) 1723 // Pattern complexity = 6 cost = 1 size = 0 1724 1725 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1726 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc) 1727 // Pattern complexity = 6 cost = 1 size = 0 1728 1729 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1730 // Emits: (t2Bcc:void (bb:Other):$dst, (imm:i32):$cc) 1731 // Pattern complexity = 6 cost = 1 size = 0 1732 1733 unsigned Opc = Subtarget->isThumb() ? 1734 ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; 1735 SDValue Chain = N->getOperand(0); 1736 SDValue N1 = N->getOperand(1); 1737 SDValue N2 = N->getOperand(2); 1738 SDValue N3 = N->getOperand(3); 1739 SDValue InFlag = N->getOperand(4); 1740 assert(N1.getOpcode() == ISD::BasicBlock); 1741 assert(N2.getOpcode() == ISD::Constant); 1742 assert(N3.getOpcode() == ISD::Register); 1743 1744 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1745 cast<ConstantSDNode>(N2)->getZExtValue()), 1746 MVT::i32); 1747 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; 1748 SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other, 1749 MVT::Flag, Ops, 5); 1750 Chain = SDValue(ResNode, 0); 1751 if (N->getNumValues() == 2) { 1752 InFlag = SDValue(ResNode, 1); 1753 ReplaceUses(SDValue(N, 1), InFlag); 1754 } 1755 ReplaceUses(SDValue(N, 0), 1756 SDValue(Chain.getNode(), Chain.getResNo())); 1757 return NULL; 1758 } 1759 case ARMISD::CMOV: 1760 return SelectCMOVOp(N); 1761 case ARMISD::CNEG: { 1762 EVT VT = N->getValueType(0); 1763 SDValue N0 = N->getOperand(0); 1764 SDValue N1 = N->getOperand(1); 1765 SDValue N2 = N->getOperand(2); 1766 SDValue N3 = N->getOperand(3); 1767 SDValue InFlag = N->getOperand(4); 1768 assert(N2.getOpcode() == ISD::Constant); 1769 assert(N3.getOpcode() == ISD::Register); 1770 1771 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1772 cast<ConstantSDNode>(N2)->getZExtValue()), 1773 MVT::i32); 1774 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 1775 unsigned Opc = 0; 1776 switch (VT.getSimpleVT().SimpleTy) { 1777 default: assert(false && "Illegal conditional move type!"); 1778 break; 1779 case MVT::f32: 1780 Opc = ARM::VNEGScc; 1781 break; 1782 case MVT::f64: 1783 Opc = ARM::VNEGDcc; 1784 break; 1785 } 1786 return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5); 1787 } 1788 1789 case ARMISD::VZIP: { 1790 unsigned Opc = 0; 1791 EVT VT = N->getValueType(0); 1792 switch (VT.getSimpleVT().SimpleTy) { 1793 default: return NULL; 1794 case MVT::v8i8: Opc = ARM::VZIPd8; break; 1795 case MVT::v4i16: Opc = ARM::VZIPd16; break; 1796 case MVT::v2f32: 1797 case MVT::v2i32: Opc = ARM::VZIPd32; break; 1798 case MVT::v16i8: Opc = ARM::VZIPq8; break; 1799 case MVT::v8i16: Opc = ARM::VZIPq16; break; 1800 case MVT::v4f32: 1801 case MVT::v4i32: Opc = ARM::VZIPq32; break; 1802 } 1803 SDValue Pred = getAL(CurDAG); 1804 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1805 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 1806 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); 1807 } 1808 case ARMISD::VUZP: { 1809 unsigned Opc = 0; 1810 EVT VT = N->getValueType(0); 1811 switch (VT.getSimpleVT().SimpleTy) { 1812 default: return NULL; 1813 case MVT::v8i8: Opc = ARM::VUZPd8; break; 1814 case MVT::v4i16: Opc = ARM::VUZPd16; break; 1815 case MVT::v2f32: 1816 case MVT::v2i32: Opc = ARM::VUZPd32; break; 1817 case MVT::v16i8: Opc = ARM::VUZPq8; break; 1818 case MVT::v8i16: Opc = ARM::VUZPq16; break; 1819 case MVT::v4f32: 1820 case MVT::v4i32: Opc = ARM::VUZPq32; break; 1821 } 1822 SDValue Pred = getAL(CurDAG); 1823 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1824 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 1825 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); 1826 } 1827 case ARMISD::VTRN: { 1828 unsigned Opc = 0; 1829 EVT VT = N->getValueType(0); 1830 switch (VT.getSimpleVT().SimpleTy) { 1831 default: return NULL; 1832 case MVT::v8i8: Opc = ARM::VTRNd8; break; 1833 case MVT::v4i16: Opc = ARM::VTRNd16; break; 1834 case MVT::v2f32: 1835 case MVT::v2i32: Opc = ARM::VTRNd32; break; 1836 case MVT::v16i8: Opc = ARM::VTRNq8; break; 1837 case MVT::v8i16: Opc = ARM::VTRNq16; break; 1838 case MVT::v4f32: 1839 case MVT::v4i32: Opc = ARM::VTRNq32; break; 1840 } 1841 SDValue Pred = getAL(CurDAG); 1842 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 1843 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; 1844 return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); 1845 } 1846 1847 case ISD::INTRINSIC_VOID: 1848 case ISD::INTRINSIC_W_CHAIN: { 1849 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 1850 switch (IntNo) { 1851 default: 1852 break; 1853 1854 case Intrinsic::arm_neon_vld1: { 1855 unsigned DOpcodes[] = { ARM::VLD1d8, ARM::VLD1d16, 1856 ARM::VLD1d32, ARM::VLD1d64 }; 1857 unsigned QOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16, 1858 ARM::VLD1q32, ARM::VLD1q64 }; 1859 return SelectVLD(N, 1, DOpcodes, QOpcodes, 0); 1860 } 1861 1862 case Intrinsic::arm_neon_vld2: { 1863 unsigned DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16, 1864 ARM::VLD2d32, ARM::VLD1q64 }; 1865 unsigned QOpcodes[] = { ARM::VLD2q8, ARM::VLD2q16, ARM::VLD2q32 }; 1866 return SelectVLD(N, 2, DOpcodes, QOpcodes, 0); 1867 } 1868 1869 case Intrinsic::arm_neon_vld3: { 1870 unsigned DOpcodes[] = { ARM::VLD3d8, ARM::VLD3d16, 1871 ARM::VLD3d32, ARM::VLD1d64T }; 1872 unsigned QOpcodes0[] = { ARM::VLD3q8_UPD, 1873 ARM::VLD3q16_UPD, 1874 ARM::VLD3q32_UPD }; 1875 unsigned QOpcodes1[] = { ARM::VLD3q8odd_UPD, 1876 ARM::VLD3q16odd_UPD, 1877 ARM::VLD3q32odd_UPD }; 1878 return SelectVLD(N, 3, DOpcodes, QOpcodes0, QOpcodes1); 1879 } 1880 1881 case Intrinsic::arm_neon_vld4: { 1882 unsigned DOpcodes[] = { ARM::VLD4d8, ARM::VLD4d16, 1883 ARM::VLD4d32, ARM::VLD1d64Q }; 1884 unsigned QOpcodes0[] = { ARM::VLD4q8_UPD, 1885 ARM::VLD4q16_UPD, 1886 ARM::VLD4q32_UPD }; 1887 unsigned QOpcodes1[] = { ARM::VLD4q8odd_UPD, 1888 ARM::VLD4q16odd_UPD, 1889 ARM::VLD4q32odd_UPD }; 1890 return SelectVLD(N, 4, DOpcodes, QOpcodes0, QOpcodes1); 1891 } 1892 1893 case Intrinsic::arm_neon_vld2lane: { 1894 unsigned DOpcodes[] = { ARM::VLD2LNd8, ARM::VLD2LNd16, ARM::VLD2LNd32 }; 1895 unsigned QOpcodes0[] = { ARM::VLD2LNq16, ARM::VLD2LNq32 }; 1896 unsigned QOpcodes1[] = { ARM::VLD2LNq16odd, ARM::VLD2LNq32odd }; 1897 return SelectVLDSTLane(N, true, 2, DOpcodes, QOpcodes0, QOpcodes1); 1898 } 1899 1900 case Intrinsic::arm_neon_vld3lane: { 1901 unsigned DOpcodes[] = { ARM::VLD3LNd8, ARM::VLD3LNd16, ARM::VLD3LNd32 }; 1902 unsigned QOpcodes0[] = { ARM::VLD3LNq16, ARM::VLD3LNq32 }; 1903 unsigned QOpcodes1[] = { ARM::VLD3LNq16odd, ARM::VLD3LNq32odd }; 1904 return SelectVLDSTLane(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1); 1905 } 1906 1907 case Intrinsic::arm_neon_vld4lane: { 1908 unsigned DOpcodes[] = { ARM::VLD4LNd8, ARM::VLD4LNd16, ARM::VLD4LNd32 }; 1909 unsigned QOpcodes0[] = { ARM::VLD4LNq16, ARM::VLD4LNq32 }; 1910 unsigned QOpcodes1[] = { ARM::VLD4LNq16odd, ARM::VLD4LNq32odd }; 1911 return SelectVLDSTLane(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1); 1912 } 1913 1914 case Intrinsic::arm_neon_vst1: { 1915 unsigned DOpcodes[] = { ARM::VST1d8, ARM::VST1d16, 1916 ARM::VST1d32, ARM::VST1d64 }; 1917 unsigned QOpcodes[] = { ARM::VST1q8, ARM::VST1q16, 1918 ARM::VST1q32, ARM::VST1q64 }; 1919 return SelectVST(N, 1, DOpcodes, QOpcodes, 0); 1920 } 1921 1922 case Intrinsic::arm_neon_vst2: { 1923 unsigned DOpcodes[] = { ARM::VST2d8, ARM::VST2d16, 1924 ARM::VST2d32, ARM::VST1q64 }; 1925 unsigned QOpcodes[] = { ARM::VST2q8, ARM::VST2q16, ARM::VST2q32 }; 1926 return SelectVST(N, 2, DOpcodes, QOpcodes, 0); 1927 } 1928 1929 case Intrinsic::arm_neon_vst3: { 1930 unsigned DOpcodes[] = { ARM::VST3d8, ARM::VST3d16, 1931 ARM::VST3d32, ARM::VST1d64T }; 1932 unsigned QOpcodes0[] = { ARM::VST3q8_UPD, 1933 ARM::VST3q16_UPD, 1934 ARM::VST3q32_UPD }; 1935 unsigned QOpcodes1[] = { ARM::VST3q8odd_UPD, 1936 ARM::VST3q16odd_UPD, 1937 ARM::VST3q32odd_UPD }; 1938 return SelectVST(N, 3, DOpcodes, QOpcodes0, QOpcodes1); 1939 } 1940 1941 case Intrinsic::arm_neon_vst4: { 1942 unsigned DOpcodes[] = { ARM::VST4d8, ARM::VST4d16, 1943 ARM::VST4d32, ARM::VST1d64Q }; 1944 unsigned QOpcodes0[] = { ARM::VST4q8_UPD, 1945 ARM::VST4q16_UPD, 1946 ARM::VST4q32_UPD }; 1947 unsigned QOpcodes1[] = { ARM::VST4q8odd_UPD, 1948 ARM::VST4q16odd_UPD, 1949 ARM::VST4q32odd_UPD }; 1950 return SelectVST(N, 4, DOpcodes, QOpcodes0, QOpcodes1); 1951 } 1952 1953 case Intrinsic::arm_neon_vst2lane: { 1954 unsigned DOpcodes[] = { ARM::VST2LNd8, ARM::VST2LNd16, ARM::VST2LNd32 }; 1955 unsigned QOpcodes0[] = { ARM::VST2LNq16, ARM::VST2LNq32 }; 1956 unsigned QOpcodes1[] = { ARM::VST2LNq16odd, ARM::VST2LNq32odd }; 1957 return SelectVLDSTLane(N, false, 2, DOpcodes, QOpcodes0, QOpcodes1); 1958 } 1959 1960 case Intrinsic::arm_neon_vst3lane: { 1961 unsigned DOpcodes[] = { ARM::VST3LNd8, ARM::VST3LNd16, ARM::VST3LNd32 }; 1962 unsigned QOpcodes0[] = { ARM::VST3LNq16, ARM::VST3LNq32 }; 1963 unsigned QOpcodes1[] = { ARM::VST3LNq16odd, ARM::VST3LNq32odd }; 1964 return SelectVLDSTLane(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); 1965 } 1966 1967 case Intrinsic::arm_neon_vst4lane: { 1968 unsigned DOpcodes[] = { ARM::VST4LNd8, ARM::VST4LNd16, ARM::VST4LNd32 }; 1969 unsigned QOpcodes0[] = { ARM::VST4LNq16, ARM::VST4LNq32 }; 1970 unsigned QOpcodes1[] = { ARM::VST4LNq16odd, ARM::VST4LNq32odd }; 1971 return SelectVLDSTLane(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); 1972 } 1973 } 1974 } 1975 } 1976 1977 return SelectCode(N); 1978} 1979 1980bool ARMDAGToDAGISel:: 1981SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 1982 std::vector<SDValue> &OutOps) { 1983 assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); 1984 // Require the address to be in a register. That is safe for all ARM 1985 // variants and it is hard to do anything much smarter without knowing 1986 // how the operand is used. 1987 OutOps.push_back(Op); 1988 return false; 1989} 1990 1991/// createARMISelDag - This pass converts a legalized DAG into a 1992/// ARM-specific DAG, ready for instruction scheduling. 1993/// 1994FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM, 1995 CodeGenOpt::Level OptLevel) { 1996 return new ARMDAGToDAGISel(TM, OptLevel); 1997} 1998