ARMISelDAGToDAG.cpp revision b0abb4dc4203b903d8d0b48a952ba0a6312eeeb7
1//===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an instruction selector for the ARM target. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ARM.h" 15#include "ARMAddressingModes.h" 16#include "ARMConstantPoolValue.h" 17#include "ARMISelLowering.h" 18#include "ARMTargetMachine.h" 19#include "llvm/CallingConv.h" 20#include "llvm/Constants.h" 21#include "llvm/DerivedTypes.h" 22#include "llvm/Function.h" 23#include "llvm/Intrinsics.h" 24#include "llvm/LLVMContext.h" 25#include "llvm/CodeGen/MachineFrameInfo.h" 26#include "llvm/CodeGen/MachineFunction.h" 27#include "llvm/CodeGen/MachineInstrBuilder.h" 28#include "llvm/CodeGen/SelectionDAG.h" 29#include "llvm/CodeGen/SelectionDAGISel.h" 30#include "llvm/Target/TargetLowering.h" 31#include "llvm/Target/TargetOptions.h" 32#include "llvm/Support/Compiler.h" 33#include "llvm/Support/Debug.h" 34#include "llvm/Support/ErrorHandling.h" 35#include "llvm/Support/raw_ostream.h" 36 37using namespace llvm; 38 39static const unsigned arm_dsubreg_0 = 5; 40static const unsigned arm_dsubreg_1 = 6; 41 42//===--------------------------------------------------------------------===// 43/// ARMDAGToDAGISel - ARM specific code to select ARM machine 44/// instructions for SelectionDAG operations. 45/// 46namespace { 47class ARMDAGToDAGISel : public SelectionDAGISel { 48 ARMBaseTargetMachine &TM; 49 50 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 51 /// make the right decision when generating code for different targets. 52 const ARMSubtarget *Subtarget; 53 54public: 55 explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm) 56 : SelectionDAGISel(tm), TM(tm), 57 Subtarget(&TM.getSubtarget<ARMSubtarget>()) { 58 } 59 60 virtual const char *getPassName() const { 61 return "ARM Instruction Selection"; 62 } 63 64 /// getI32Imm - Return a target constant with the specified value, of type i32. 65 inline SDValue getI32Imm(unsigned Imm) { 66 return CurDAG->getTargetConstant(Imm, EVT::i32); 67 } 68 69 SDNode *Select(SDValue Op); 70 virtual void InstructionSelect(); 71 bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A, 72 SDValue &B, SDValue &C); 73 bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base, 74 SDValue &Offset, SDValue &Opc); 75 bool SelectAddrMode2Offset(SDValue Op, SDValue N, 76 SDValue &Offset, SDValue &Opc); 77 bool SelectAddrMode3(SDValue Op, SDValue N, SDValue &Base, 78 SDValue &Offset, SDValue &Opc); 79 bool SelectAddrMode3Offset(SDValue Op, SDValue N, 80 SDValue &Offset, SDValue &Opc); 81 bool SelectAddrMode4(SDValue Op, SDValue N, SDValue &Addr, 82 SDValue &Mode); 83 bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base, 84 SDValue &Offset); 85 bool SelectAddrMode6(SDValue Op, SDValue N, SDValue &Addr, SDValue &Update, 86 SDValue &Opc); 87 88 bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset, 89 SDValue &Label); 90 91 bool SelectThumbAddrModeRR(SDValue Op, SDValue N, SDValue &Base, 92 SDValue &Offset); 93 bool SelectThumbAddrModeRI5(SDValue Op, SDValue N, unsigned Scale, 94 SDValue &Base, SDValue &OffImm, 95 SDValue &Offset); 96 bool SelectThumbAddrModeS1(SDValue Op, SDValue N, SDValue &Base, 97 SDValue &OffImm, SDValue &Offset); 98 bool SelectThumbAddrModeS2(SDValue Op, SDValue N, SDValue &Base, 99 SDValue &OffImm, SDValue &Offset); 100 bool SelectThumbAddrModeS4(SDValue Op, SDValue N, SDValue &Base, 101 SDValue &OffImm, SDValue &Offset); 102 bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base, 103 SDValue &OffImm); 104 105 bool SelectT2ShifterOperandReg(SDValue Op, SDValue N, 106 SDValue &BaseReg, SDValue &Opc); 107 bool SelectT2AddrModeImm12(SDValue Op, SDValue N, SDValue &Base, 108 SDValue &OffImm); 109 bool SelectT2AddrModeImm8(SDValue Op, SDValue N, SDValue &Base, 110 SDValue &OffImm); 111 bool SelectT2AddrModeImm8Offset(SDValue Op, SDValue N, 112 SDValue &OffImm); 113 bool SelectT2AddrModeImm8s4(SDValue Op, SDValue N, SDValue &Base, 114 SDValue &OffImm); 115 bool SelectT2AddrModeSoReg(SDValue Op, SDValue N, SDValue &Base, 116 SDValue &OffReg, SDValue &ShImm); 117 118 // Include the pieces autogenerated from the target description. 119#include "ARMGenDAGISel.inc" 120 121private: 122 /// SelectARMIndexedLoad - Indexed (pre/post inc/dec) load matching code for 123 /// ARM. 124 SDNode *SelectARMIndexedLoad(SDValue Op); 125 SDNode *SelectT2IndexedLoad(SDValue Op); 126 127 /// SelectDYN_ALLOC - Select dynamic alloc for Thumb. 128 SDNode *SelectDYN_ALLOC(SDValue Op); 129 130 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 131 /// inline asm expressions. 132 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 133 char ConstraintCode, 134 std::vector<SDValue> &OutOps); 135}; 136} 137 138void ARMDAGToDAGISel::InstructionSelect() { 139 DEBUG(BB->dump()); 140 141 SelectRoot(*CurDAG); 142 CurDAG->RemoveDeadNodes(); 143} 144 145bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op, 146 SDValue N, 147 SDValue &BaseReg, 148 SDValue &ShReg, 149 SDValue &Opc) { 150 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 151 152 // Don't match base register only case. That is matched to a separate 153 // lower complexity pattern with explicit register operand. 154 if (ShOpcVal == ARM_AM::no_shift) return false; 155 156 BaseReg = N.getOperand(0); 157 unsigned ShImmVal = 0; 158 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 159 ShReg = CurDAG->getRegister(0, EVT::i32); 160 ShImmVal = RHS->getZExtValue() & 31; 161 } else { 162 ShReg = N.getOperand(1); 163 } 164 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 165 EVT::i32); 166 return true; 167} 168 169bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N, 170 SDValue &Base, SDValue &Offset, 171 SDValue &Opc) { 172 if (N.getOpcode() == ISD::MUL) { 173 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 174 // X * [3,5,9] -> X + X * [2,4,8] etc. 175 int RHSC = (int)RHS->getZExtValue(); 176 if (RHSC & 1) { 177 RHSC = RHSC & ~1; 178 ARM_AM::AddrOpc AddSub = ARM_AM::add; 179 if (RHSC < 0) { 180 AddSub = ARM_AM::sub; 181 RHSC = - RHSC; 182 } 183 if (isPowerOf2_32(RHSC)) { 184 unsigned ShAmt = Log2_32(RHSC); 185 Base = Offset = N.getOperand(0); 186 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, 187 ARM_AM::lsl), 188 EVT::i32); 189 return true; 190 } 191 } 192 } 193 } 194 195 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 196 Base = N; 197 if (N.getOpcode() == ISD::FrameIndex) { 198 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 199 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 200 } else if (N.getOpcode() == ARMISD::Wrapper) { 201 Base = N.getOperand(0); 202 } 203 Offset = CurDAG->getRegister(0, EVT::i32); 204 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, 205 ARM_AM::no_shift), 206 EVT::i32); 207 return true; 208 } 209 210 // Match simple R +/- imm12 operands. 211 if (N.getOpcode() == ISD::ADD) 212 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 213 int RHSC = (int)RHS->getZExtValue(); 214 if ((RHSC >= 0 && RHSC < 0x1000) || 215 (RHSC < 0 && RHSC > -0x1000)) { // 12 bits. 216 Base = N.getOperand(0); 217 if (Base.getOpcode() == ISD::FrameIndex) { 218 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 219 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 220 } 221 Offset = CurDAG->getRegister(0, EVT::i32); 222 223 ARM_AM::AddrOpc AddSub = ARM_AM::add; 224 if (RHSC < 0) { 225 AddSub = ARM_AM::sub; 226 RHSC = - RHSC; 227 } 228 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC, 229 ARM_AM::no_shift), 230 EVT::i32); 231 return true; 232 } 233 } 234 235 // Otherwise this is R +/- [possibly shifted] R 236 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub; 237 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1)); 238 unsigned ShAmt = 0; 239 240 Base = N.getOperand(0); 241 Offset = N.getOperand(1); 242 243 if (ShOpcVal != ARM_AM::no_shift) { 244 // Check to see if the RHS of the shift is a constant, if not, we can't fold 245 // it. 246 if (ConstantSDNode *Sh = 247 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) { 248 ShAmt = Sh->getZExtValue(); 249 Offset = N.getOperand(1).getOperand(0); 250 } else { 251 ShOpcVal = ARM_AM::no_shift; 252 } 253 } 254 255 // Try matching (R shl C) + (R). 256 if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) { 257 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0)); 258 if (ShOpcVal != ARM_AM::no_shift) { 259 // Check to see if the RHS of the shift is a constant, if not, we can't 260 // fold it. 261 if (ConstantSDNode *Sh = 262 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) { 263 ShAmt = Sh->getZExtValue(); 264 Offset = N.getOperand(0).getOperand(0); 265 Base = N.getOperand(1); 266 } else { 267 ShOpcVal = ARM_AM::no_shift; 268 } 269 } 270 } 271 272 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 273 EVT::i32); 274 return true; 275} 276 277bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDValue Op, SDValue N, 278 SDValue &Offset, SDValue &Opc) { 279 unsigned Opcode = Op.getOpcode(); 280 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 281 ? cast<LoadSDNode>(Op)->getAddressingMode() 282 : cast<StoreSDNode>(Op)->getAddressingMode(); 283 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 284 ? ARM_AM::add : ARM_AM::sub; 285 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 286 int Val = (int)C->getZExtValue(); 287 if (Val >= 0 && Val < 0x1000) { // 12 bits. 288 Offset = CurDAG->getRegister(0, EVT::i32); 289 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, 290 ARM_AM::no_shift), 291 EVT::i32); 292 return true; 293 } 294 } 295 296 Offset = N; 297 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 298 unsigned ShAmt = 0; 299 if (ShOpcVal != ARM_AM::no_shift) { 300 // Check to see if the RHS of the shift is a constant, if not, we can't fold 301 // it. 302 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 303 ShAmt = Sh->getZExtValue(); 304 Offset = N.getOperand(0); 305 } else { 306 ShOpcVal = ARM_AM::no_shift; 307 } 308 } 309 310 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 311 EVT::i32); 312 return true; 313} 314 315 316bool ARMDAGToDAGISel::SelectAddrMode3(SDValue Op, SDValue N, 317 SDValue &Base, SDValue &Offset, 318 SDValue &Opc) { 319 if (N.getOpcode() == ISD::SUB) { 320 // X - C is canonicalize to X + -C, no need to handle it here. 321 Base = N.getOperand(0); 322 Offset = N.getOperand(1); 323 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),EVT::i32); 324 return true; 325 } 326 327 if (N.getOpcode() != ISD::ADD) { 328 Base = N; 329 if (N.getOpcode() == ISD::FrameIndex) { 330 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 331 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 332 } 333 Offset = CurDAG->getRegister(0, EVT::i32); 334 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),EVT::i32); 335 return true; 336 } 337 338 // If the RHS is +/- imm8, fold into addr mode. 339 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 340 int RHSC = (int)RHS->getZExtValue(); 341 if ((RHSC >= 0 && RHSC < 256) || 342 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 343 Base = N.getOperand(0); 344 if (Base.getOpcode() == ISD::FrameIndex) { 345 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 346 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 347 } 348 Offset = CurDAG->getRegister(0, EVT::i32); 349 350 ARM_AM::AddrOpc AddSub = ARM_AM::add; 351 if (RHSC < 0) { 352 AddSub = ARM_AM::sub; 353 RHSC = - RHSC; 354 } 355 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),EVT::i32); 356 return true; 357 } 358 } 359 360 Base = N.getOperand(0); 361 Offset = N.getOperand(1); 362 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), EVT::i32); 363 return true; 364} 365 366bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N, 367 SDValue &Offset, SDValue &Opc) { 368 unsigned Opcode = Op.getOpcode(); 369 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 370 ? cast<LoadSDNode>(Op)->getAddressingMode() 371 : cast<StoreSDNode>(Op)->getAddressingMode(); 372 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 373 ? ARM_AM::add : ARM_AM::sub; 374 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 375 int Val = (int)C->getZExtValue(); 376 if (Val >= 0 && Val < 256) { 377 Offset = CurDAG->getRegister(0, EVT::i32); 378 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), EVT::i32); 379 return true; 380 } 381 } 382 383 Offset = N; 384 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), EVT::i32); 385 return true; 386} 387 388bool ARMDAGToDAGISel::SelectAddrMode4(SDValue Op, SDValue N, 389 SDValue &Addr, SDValue &Mode) { 390 Addr = N; 391 Mode = CurDAG->getTargetConstant(0, EVT::i32); 392 return true; 393} 394 395bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N, 396 SDValue &Base, SDValue &Offset) { 397 if (N.getOpcode() != ISD::ADD) { 398 Base = N; 399 if (N.getOpcode() == ISD::FrameIndex) { 400 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 401 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 402 } else if (N.getOpcode() == ARMISD::Wrapper) { 403 Base = N.getOperand(0); 404 } 405 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 406 EVT::i32); 407 return true; 408 } 409 410 // If the RHS is +/- imm8, fold into addr mode. 411 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 412 int RHSC = (int)RHS->getZExtValue(); 413 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied by 4. 414 RHSC >>= 2; 415 if ((RHSC >= 0 && RHSC < 256) || 416 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 417 Base = N.getOperand(0); 418 if (Base.getOpcode() == ISD::FrameIndex) { 419 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 420 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 421 } 422 423 ARM_AM::AddrOpc AddSub = ARM_AM::add; 424 if (RHSC < 0) { 425 AddSub = ARM_AM::sub; 426 RHSC = - RHSC; 427 } 428 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC), 429 EVT::i32); 430 return true; 431 } 432 } 433 } 434 435 Base = N; 436 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 437 EVT::i32); 438 return true; 439} 440 441bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N, 442 SDValue &Addr, SDValue &Update, 443 SDValue &Opc) { 444 Addr = N; 445 // The optional writeback is handled in ARMLoadStoreOpt. 446 Update = CurDAG->getRegister(0, EVT::i32); 447 Opc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(false), EVT::i32); 448 return true; 449} 450 451bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N, 452 SDValue &Offset, SDValue &Label) { 453 if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { 454 Offset = N.getOperand(0); 455 SDValue N1 = N.getOperand(1); 456 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(), 457 EVT::i32); 458 return true; 459 } 460 return false; 461} 462 463bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op, SDValue N, 464 SDValue &Base, SDValue &Offset){ 465 // FIXME dl should come from the parent load or store, not the address 466 DebugLoc dl = Op.getDebugLoc(); 467 if (N.getOpcode() != ISD::ADD) { 468 ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N); 469 if (!NC || NC->getZExtValue() != 0) 470 return false; 471 472 Base = Offset = N; 473 return true; 474 } 475 476 Base = N.getOperand(0); 477 Offset = N.getOperand(1); 478 return true; 479} 480 481bool 482ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op, SDValue N, 483 unsigned Scale, SDValue &Base, 484 SDValue &OffImm, SDValue &Offset) { 485 if (Scale == 4) { 486 SDValue TmpBase, TmpOffImm; 487 if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm)) 488 return false; // We want to select tLDRspi / tSTRspi instead. 489 if (N.getOpcode() == ARMISD::Wrapper && 490 N.getOperand(0).getOpcode() == ISD::TargetConstantPool) 491 return false; // We want to select tLDRpci instead. 492 } 493 494 if (N.getOpcode() != ISD::ADD) { 495 Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N; 496 Offset = CurDAG->getRegister(0, EVT::i32); 497 OffImm = CurDAG->getTargetConstant(0, EVT::i32); 498 return true; 499 } 500 501 // Thumb does not have [sp, r] address mode. 502 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 503 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1)); 504 if ((LHSR && LHSR->getReg() == ARM::SP) || 505 (RHSR && RHSR->getReg() == ARM::SP)) { 506 Base = N; 507 Offset = CurDAG->getRegister(0, EVT::i32); 508 OffImm = CurDAG->getTargetConstant(0, EVT::i32); 509 return true; 510 } 511 512 // If the RHS is + imm5 * scale, fold into addr mode. 513 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 514 int RHSC = (int)RHS->getZExtValue(); 515 if ((RHSC & (Scale-1)) == 0) { // The constant is implicitly multiplied. 516 RHSC /= Scale; 517 if (RHSC >= 0 && RHSC < 32) { 518 Base = N.getOperand(0); 519 Offset = CurDAG->getRegister(0, EVT::i32); 520 OffImm = CurDAG->getTargetConstant(RHSC, EVT::i32); 521 return true; 522 } 523 } 524 } 525 526 Base = N.getOperand(0); 527 Offset = N.getOperand(1); 528 OffImm = CurDAG->getTargetConstant(0, EVT::i32); 529 return true; 530} 531 532bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue Op, SDValue N, 533 SDValue &Base, SDValue &OffImm, 534 SDValue &Offset) { 535 return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset); 536} 537 538bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue Op, SDValue N, 539 SDValue &Base, SDValue &OffImm, 540 SDValue &Offset) { 541 return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset); 542} 543 544bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue Op, SDValue N, 545 SDValue &Base, SDValue &OffImm, 546 SDValue &Offset) { 547 return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset); 548} 549 550bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N, 551 SDValue &Base, SDValue &OffImm) { 552 if (N.getOpcode() == ISD::FrameIndex) { 553 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 554 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 555 OffImm = CurDAG->getTargetConstant(0, EVT::i32); 556 return true; 557 } 558 559 if (N.getOpcode() != ISD::ADD) 560 return false; 561 562 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 563 if (N.getOperand(0).getOpcode() == ISD::FrameIndex || 564 (LHSR && LHSR->getReg() == ARM::SP)) { 565 // If the RHS is + imm8 * scale, fold into addr mode. 566 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 567 int RHSC = (int)RHS->getZExtValue(); 568 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied. 569 RHSC >>= 2; 570 if (RHSC >= 0 && RHSC < 256) { 571 Base = N.getOperand(0); 572 if (Base.getOpcode() == ISD::FrameIndex) { 573 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 574 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 575 } 576 OffImm = CurDAG->getTargetConstant(RHSC, EVT::i32); 577 return true; 578 } 579 } 580 } 581 } 582 583 return false; 584} 585 586bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue Op, SDValue N, 587 SDValue &BaseReg, 588 SDValue &Opc) { 589 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 590 591 // Don't match base register only case. That is matched to a separate 592 // lower complexity pattern with explicit register operand. 593 if (ShOpcVal == ARM_AM::no_shift) return false; 594 595 BaseReg = N.getOperand(0); 596 unsigned ShImmVal = 0; 597 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 598 ShImmVal = RHS->getZExtValue() & 31; 599 Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal)); 600 return true; 601 } 602 603 return false; 604} 605 606bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, 607 SDValue &Base, SDValue &OffImm) { 608 // Match simple R + imm12 operands. 609 610 // Match frame index... 611 if ((N.getOpcode() != ISD::ADD) && (N.getOpcode() != ISD::SUB)) { 612 if (N.getOpcode() == ISD::FrameIndex) { 613 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 614 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 615 OffImm = CurDAG->getTargetConstant(0, EVT::i32); 616 return true; 617 } 618 return false; 619 } 620 621 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 622 int RHSC = (int)RHS->getZExtValue(); 623 if (N.getOpcode() == ISD::SUB) 624 RHSC = -RHSC; 625 626 if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits (unsigned) 627 Base = N.getOperand(0); 628 if (Base.getOpcode() == ISD::FrameIndex) { 629 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 630 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 631 } 632 OffImm = CurDAG->getTargetConstant(RHSC, EVT::i32); 633 return true; 634 } 635 } 636 637 return false; 638} 639 640bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue Op, SDValue N, 641 SDValue &Base, SDValue &OffImm) { 642 // Match simple R - imm8 operands. 643 if ((N.getOpcode() == ISD::ADD) || (N.getOpcode() == ISD::SUB)) { 644 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 645 int RHSC = (int)RHS->getSExtValue(); 646 if (N.getOpcode() == ISD::SUB) 647 RHSC = -RHSC; 648 649 if ((RHSC >= -255) && (RHSC <= 0)) { // 8 bits (always negative) 650 Base = N.getOperand(0); 651 if (Base.getOpcode() == ISD::FrameIndex) { 652 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 653 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 654 } 655 OffImm = CurDAG->getTargetConstant(RHSC, EVT::i32); 656 return true; 657 } 658 } 659 } 660 661 return false; 662} 663 664bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDValue Op, SDValue N, 665 SDValue &OffImm){ 666 unsigned Opcode = Op.getOpcode(); 667 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 668 ? cast<LoadSDNode>(Op)->getAddressingMode() 669 : cast<StoreSDNode>(Op)->getAddressingMode(); 670 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N)) { 671 int RHSC = (int)RHS->getZExtValue(); 672 if (RHSC >= 0 && RHSC < 0x100) { // 8 bits. 673 OffImm = ((AM == ISD::PRE_INC) || (AM == ISD::POST_INC)) 674 ? CurDAG->getTargetConstant(RHSC, EVT::i32) 675 : CurDAG->getTargetConstant(-RHSC, EVT::i32); 676 return true; 677 } 678 } 679 680 return false; 681} 682 683bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDValue Op, SDValue N, 684 SDValue &Base, SDValue &OffImm) { 685 if (N.getOpcode() == ISD::ADD) { 686 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 687 int RHSC = (int)RHS->getZExtValue(); 688 if (((RHSC & 0x3) == 0) && 689 ((RHSC >= 0 && RHSC < 0x400) || (RHSC < 0 && RHSC > -0x400))) { // 8 bits. 690 Base = N.getOperand(0); 691 OffImm = CurDAG->getTargetConstant(RHSC, EVT::i32); 692 return true; 693 } 694 } 695 } else if (N.getOpcode() == ISD::SUB) { 696 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 697 int RHSC = (int)RHS->getZExtValue(); 698 if (((RHSC & 0x3) == 0) && (RHSC >= 0 && RHSC < 0x400)) { // 8 bits. 699 Base = N.getOperand(0); 700 OffImm = CurDAG->getTargetConstant(-RHSC, EVT::i32); 701 return true; 702 } 703 } 704 } 705 706 return false; 707} 708 709bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue Op, SDValue N, 710 SDValue &Base, 711 SDValue &OffReg, SDValue &ShImm) { 712 // Base only. 713 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 714 Base = N; 715 if (N.getOpcode() == ISD::FrameIndex) { 716 return false; // we want to select t2LDRri12 instead 717 } else if (N.getOpcode() == ARMISD::Wrapper) { 718 Base = N.getOperand(0); 719 if (Base.getOpcode() == ISD::TargetConstantPool) 720 return false; // We want to select t2LDRpci instead. 721 } 722 OffReg = CurDAG->getRegister(0, EVT::i32); 723 ShImm = CurDAG->getTargetConstant(0, EVT::i32); 724 return true; 725 } 726 727 // Leave (R +/- imm) for other address modes... unless they can't 728 // handle them 729 if (dyn_cast<ConstantSDNode>(N.getOperand(1)) != NULL) { 730 SDValue OffImm; 731 if (SelectT2AddrModeImm12(Op, N, Base, OffImm) || 732 SelectT2AddrModeImm8 (Op, N, Base, OffImm)) 733 return false; 734 } 735 736 // Thumb2 does not support (R - R) or (R - (R << [1,2,3])). 737 if (N.getOpcode() == ISD::SUB) { 738 Base = N; 739 OffReg = CurDAG->getRegister(0, EVT::i32); 740 ShImm = CurDAG->getTargetConstant(0, EVT::i32); 741 return true; 742 } 743 744 assert(N.getOpcode() == ISD::ADD); 745 746 // Look for (R + R) or (R + (R << [1,2,3])). 747 unsigned ShAmt = 0; 748 Base = N.getOperand(0); 749 OffReg = N.getOperand(1); 750 751 // Swap if it is ((R << c) + R). 752 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg); 753 if (ShOpcVal != ARM_AM::lsl) { 754 ShOpcVal = ARM_AM::getShiftOpcForNode(Base); 755 if (ShOpcVal == ARM_AM::lsl) 756 std::swap(Base, OffReg); 757 } 758 759 if (ShOpcVal == ARM_AM::lsl) { 760 // Check to see if the RHS of the shift is a constant, if not, we can't fold 761 // it. 762 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(OffReg.getOperand(1))) { 763 ShAmt = Sh->getZExtValue(); 764 if (ShAmt >= 4) { 765 ShAmt = 0; 766 ShOpcVal = ARM_AM::no_shift; 767 } else 768 OffReg = OffReg.getOperand(0); 769 } else { 770 ShOpcVal = ARM_AM::no_shift; 771 } 772 } 773 774 ShImm = CurDAG->getTargetConstant(ShAmt, EVT::i32); 775 776 return true; 777} 778 779//===--------------------------------------------------------------------===// 780 781/// getAL - Returns a ARMCC::AL immediate node. 782static inline SDValue getAL(SelectionDAG *CurDAG) { 783 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, EVT::i32); 784} 785 786SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) { 787 LoadSDNode *LD = cast<LoadSDNode>(Op); 788 ISD::MemIndexedMode AM = LD->getAddressingMode(); 789 if (AM == ISD::UNINDEXED) 790 return NULL; 791 792 EVT LoadedVT = LD->getMemoryVT(); 793 SDValue Offset, AMOpc; 794 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 795 unsigned Opcode = 0; 796 bool Match = false; 797 if (LoadedVT == EVT::i32 && 798 SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { 799 Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST; 800 Match = true; 801 } else if (LoadedVT == EVT::i16 && 802 SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { 803 Match = true; 804 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) 805 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) 806 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); 807 } else if (LoadedVT == EVT::i8 || LoadedVT == EVT::i1) { 808 if (LD->getExtensionType() == ISD::SEXTLOAD) { 809 if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { 810 Match = true; 811 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; 812 } 813 } else { 814 if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { 815 Match = true; 816 Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST; 817 } 818 } 819 } 820 821 if (Match) { 822 SDValue Chain = LD->getChain(); 823 SDValue Base = LD->getBasePtr(); 824 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), 825 CurDAG->getRegister(0, EVT::i32), Chain }; 826 return CurDAG->getTargetNode(Opcode, Op.getDebugLoc(), EVT::i32, EVT::i32, 827 EVT::Other, Ops, 6); 828 } 829 830 return NULL; 831} 832 833SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDValue Op) { 834 LoadSDNode *LD = cast<LoadSDNode>(Op); 835 ISD::MemIndexedMode AM = LD->getAddressingMode(); 836 if (AM == ISD::UNINDEXED) 837 return NULL; 838 839 EVT LoadedVT = LD->getMemoryVT(); 840 bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD; 841 SDValue Offset; 842 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 843 unsigned Opcode = 0; 844 bool Match = false; 845 if (SelectT2AddrModeImm8Offset(Op, LD->getOffset(), Offset)) { 846 switch (LoadedVT.getSimpleVT()) { 847 case EVT::i32: 848 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST; 849 break; 850 case EVT::i16: 851 if (isSExtLd) 852 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST; 853 else 854 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST; 855 break; 856 case EVT::i8: 857 case EVT::i1: 858 if (isSExtLd) 859 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST; 860 else 861 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST; 862 break; 863 default: 864 return NULL; 865 } 866 Match = true; 867 } 868 869 if (Match) { 870 SDValue Chain = LD->getChain(); 871 SDValue Base = LD->getBasePtr(); 872 SDValue Ops[]= { Base, Offset, getAL(CurDAG), 873 CurDAG->getRegister(0, EVT::i32), Chain }; 874 return CurDAG->getTargetNode(Opcode, Op.getDebugLoc(), EVT::i32, EVT::i32, 875 EVT::Other, Ops, 5); 876 } 877 878 return NULL; 879} 880 881SDNode *ARMDAGToDAGISel::SelectDYN_ALLOC(SDValue Op) { 882 SDNode *N = Op.getNode(); 883 DebugLoc dl = N->getDebugLoc(); 884 EVT VT = Op.getValueType(); 885 SDValue Chain = Op.getOperand(0); 886 SDValue Size = Op.getOperand(1); 887 SDValue Align = Op.getOperand(2); 888 SDValue SP = CurDAG->getRegister(ARM::SP, EVT::i32); 889 int32_t AlignVal = cast<ConstantSDNode>(Align)->getSExtValue(); 890 if (AlignVal < 0) 891 // We need to align the stack. Use Thumb1 tAND which is the only thumb 892 // instruction that can read and write SP. This matches to a pseudo 893 // instruction that has a chain to ensure the result is written back to 894 // the stack pointer. 895 SP = SDValue(CurDAG->getTargetNode(ARM::tANDsp, dl, VT, SP, Align), 0); 896 897 bool isC = isa<ConstantSDNode>(Size); 898 uint32_t C = isC ? cast<ConstantSDNode>(Size)->getZExtValue() : ~0UL; 899 // Handle the most common case for both Thumb1 and Thumb2: 900 // tSUBspi - immediate is between 0 ... 508 inclusive. 901 if (C <= 508 && ((C & 3) == 0)) 902 // FIXME: tSUBspi encode scale 4 implicitly. 903 return CurDAG->SelectNodeTo(N, ARM::tSUBspi_, VT, EVT::Other, SP, 904 CurDAG->getTargetConstant(C/4, EVT::i32), 905 Chain); 906 907 if (Subtarget->isThumb1Only()) { 908 // Use tADDrSPr since Thumb1 does not have a sub r, sp, r. ARMISelLowering 909 // should have negated the size operand already. FIXME: We can't insert 910 // new target independent node at this stage so we are forced to negate 911 // it earlier. Is there a better solution? 912 return CurDAG->SelectNodeTo(N, ARM::tADDspr_, VT, EVT::Other, SP, Size, 913 Chain); 914 } else if (Subtarget->isThumb2()) { 915 if (isC && Predicate_t2_so_imm(Size.getNode())) { 916 // t2SUBrSPi 917 SDValue Ops[] = { SP, CurDAG->getTargetConstant(C, EVT::i32), Chain }; 918 return CurDAG->SelectNodeTo(N, ARM::t2SUBrSPi_, VT, EVT::Other, Ops, 3); 919 } else if (isC && Predicate_imm0_4095(Size.getNode())) { 920 // t2SUBrSPi12 921 SDValue Ops[] = { SP, CurDAG->getTargetConstant(C, EVT::i32), Chain }; 922 return CurDAG->SelectNodeTo(N, ARM::t2SUBrSPi12_, VT, EVT::Other, Ops, 3); 923 } else { 924 // t2SUBrSPs 925 SDValue Ops[] = { SP, Size, 926 getI32Imm(ARM_AM::getSORegOpc(ARM_AM::lsl,0)), Chain }; 927 return CurDAG->SelectNodeTo(N, ARM::t2SUBrSPs_, VT, EVT::Other, Ops, 4); 928 } 929 } 930 931 // FIXME: Add ADD / SUB sp instructions for ARM. 932 return 0; 933} 934 935SDNode *ARMDAGToDAGISel::Select(SDValue Op) { 936 SDNode *N = Op.getNode(); 937 DebugLoc dl = N->getDebugLoc(); 938 939 if (N->isMachineOpcode()) 940 return NULL; // Already selected. 941 942 switch (N->getOpcode()) { 943 default: break; 944 case ISD::Constant: { 945 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 946 bool UseCP = true; 947 if (Subtarget->isThumb()) { 948 if (Subtarget->hasThumb2()) 949 // Thumb2 has the MOVT instruction, so all immediates can 950 // be done with MOV + MOVT, at worst. 951 UseCP = 0; 952 else 953 UseCP = (Val > 255 && // MOV 954 ~Val > 255 && // MOV + MVN 955 !ARM_AM::isThumbImmShiftedVal(Val)); // MOV + LSL 956 } else 957 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV 958 ARM_AM::getSOImmVal(~Val) == -1 && // MVN 959 !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs. 960 if (UseCP) { 961 SDValue CPIdx = 962 CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val), 963 TLI.getPointerTy()); 964 965 SDNode *ResNode; 966 if (Subtarget->isThumb1Only()) { 967 SDValue Pred = CurDAG->getTargetConstant(0xEULL, EVT::i32); 968 SDValue PredReg = CurDAG->getRegister(0, EVT::i32); 969 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() }; 970 ResNode = CurDAG->getTargetNode(ARM::tLDRcp, dl, EVT::i32, EVT::Other, 971 Ops, 4); 972 } else { 973 SDValue Ops[] = { 974 CPIdx, 975 CurDAG->getRegister(0, EVT::i32), 976 CurDAG->getTargetConstant(0, EVT::i32), 977 getAL(CurDAG), 978 CurDAG->getRegister(0, EVT::i32), 979 CurDAG->getEntryNode() 980 }; 981 ResNode=CurDAG->getTargetNode(ARM::LDRcp, dl, EVT::i32, EVT::Other, 982 Ops, 6); 983 } 984 ReplaceUses(Op, SDValue(ResNode, 0)); 985 return NULL; 986 } 987 988 // Other cases are autogenerated. 989 break; 990 } 991 case ISD::FrameIndex: { 992 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. 993 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 994 SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 995 if (Subtarget->isThumb1Only()) { 996 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, EVT::i32, TFI, 997 CurDAG->getTargetConstant(0, EVT::i32)); 998 } else { 999 unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ? 1000 ARM::t2ADDri : ARM::ADDri); 1001 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, EVT::i32), 1002 getAL(CurDAG), CurDAG->getRegister(0, EVT::i32), 1003 CurDAG->getRegister(0, EVT::i32) }; 1004 return CurDAG->SelectNodeTo(N, Opc, EVT::i32, Ops, 5); 1005 } 1006 } 1007 case ARMISD::DYN_ALLOC: 1008 return SelectDYN_ALLOC(Op); 1009 case ISD::MUL: 1010 if (Subtarget->isThumb1Only()) 1011 break; 1012 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { 1013 unsigned RHSV = C->getZExtValue(); 1014 if (!RHSV) break; 1015 if (isPowerOf2_32(RHSV-1)) { // 2^n+1? 1016 unsigned ShImm = Log2_32(RHSV-1); 1017 if (ShImm >= 32) 1018 break; 1019 SDValue V = Op.getOperand(0); 1020 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 1021 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, EVT::i32); 1022 SDValue Reg0 = CurDAG->getRegister(0, EVT::i32); 1023 if (Subtarget->isThumb()) { 1024 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1025 return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, EVT::i32, Ops, 6); 1026 } else { 1027 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1028 return CurDAG->SelectNodeTo(N, ARM::ADDrs, EVT::i32, Ops, 7); 1029 } 1030 } 1031 if (isPowerOf2_32(RHSV+1)) { // 2^n-1? 1032 unsigned ShImm = Log2_32(RHSV+1); 1033 if (ShImm >= 32) 1034 break; 1035 SDValue V = Op.getOperand(0); 1036 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 1037 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, EVT::i32); 1038 SDValue Reg0 = CurDAG->getRegister(0, EVT::i32); 1039 if (Subtarget->isThumb()) { 1040 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0 }; 1041 return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, EVT::i32, Ops, 5); 1042 } else { 1043 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 1044 return CurDAG->SelectNodeTo(N, ARM::RSBrs, EVT::i32, Ops, 7); 1045 } 1046 } 1047 } 1048 break; 1049 case ARMISD::FMRRD: 1050 return CurDAG->getTargetNode(ARM::FMRRD, dl, EVT::i32, EVT::i32, 1051 Op.getOperand(0), getAL(CurDAG), 1052 CurDAG->getRegister(0, EVT::i32)); 1053 case ISD::UMUL_LOHI: { 1054 if (Subtarget->isThumb1Only()) 1055 break; 1056 if (Subtarget->isThumb()) { 1057 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 1058 getAL(CurDAG), CurDAG->getRegister(0, EVT::i32), 1059 CurDAG->getRegister(0, EVT::i32) }; 1060 return CurDAG->getTargetNode(ARM::t2UMULL, dl, EVT::i32, EVT::i32, Ops,4); 1061 } else { 1062 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 1063 getAL(CurDAG), CurDAG->getRegister(0, EVT::i32), 1064 CurDAG->getRegister(0, EVT::i32) }; 1065 return CurDAG->getTargetNode(ARM::UMULL, dl, EVT::i32, EVT::i32, Ops, 5); 1066 } 1067 } 1068 case ISD::SMUL_LOHI: { 1069 if (Subtarget->isThumb1Only()) 1070 break; 1071 if (Subtarget->isThumb()) { 1072 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 1073 getAL(CurDAG), CurDAG->getRegister(0, EVT::i32) }; 1074 return CurDAG->getTargetNode(ARM::t2SMULL, dl, EVT::i32, EVT::i32, Ops,4); 1075 } else { 1076 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 1077 getAL(CurDAG), CurDAG->getRegister(0, EVT::i32), 1078 CurDAG->getRegister(0, EVT::i32) }; 1079 return CurDAG->getTargetNode(ARM::SMULL, dl, EVT::i32, EVT::i32, Ops, 5); 1080 } 1081 } 1082 case ISD::LOAD: { 1083 SDNode *ResNode = 0; 1084 if (Subtarget->isThumb() && Subtarget->hasThumb2()) 1085 ResNode = SelectT2IndexedLoad(Op); 1086 else 1087 ResNode = SelectARMIndexedLoad(Op); 1088 if (ResNode) 1089 return ResNode; 1090 // Other cases are autogenerated. 1091 break; 1092 } 1093 case ARMISD::BRCOND: { 1094 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1095 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc) 1096 // Pattern complexity = 6 cost = 1 size = 0 1097 1098 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1099 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc) 1100 // Pattern complexity = 6 cost = 1 size = 0 1101 1102 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1103 // Emits: (t2Bcc:void (bb:Other):$dst, (imm:i32):$cc) 1104 // Pattern complexity = 6 cost = 1 size = 0 1105 1106 unsigned Opc = Subtarget->isThumb() ? 1107 ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; 1108 SDValue Chain = Op.getOperand(0); 1109 SDValue N1 = Op.getOperand(1); 1110 SDValue N2 = Op.getOperand(2); 1111 SDValue N3 = Op.getOperand(3); 1112 SDValue InFlag = Op.getOperand(4); 1113 assert(N1.getOpcode() == ISD::BasicBlock); 1114 assert(N2.getOpcode() == ISD::Constant); 1115 assert(N3.getOpcode() == ISD::Register); 1116 1117 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1118 cast<ConstantSDNode>(N2)->getZExtValue()), 1119 EVT::i32); 1120 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; 1121 SDNode *ResNode = CurDAG->getTargetNode(Opc, dl, EVT::Other, 1122 EVT::Flag, Ops, 5); 1123 Chain = SDValue(ResNode, 0); 1124 if (Op.getNode()->getNumValues() == 2) { 1125 InFlag = SDValue(ResNode, 1); 1126 ReplaceUses(SDValue(Op.getNode(), 1), InFlag); 1127 } 1128 ReplaceUses(SDValue(Op.getNode(), 0), SDValue(Chain.getNode(), Chain.getResNo())); 1129 return NULL; 1130 } 1131 case ARMISD::CMOV: { 1132 EVT VT = Op.getValueType(); 1133 SDValue N0 = Op.getOperand(0); 1134 SDValue N1 = Op.getOperand(1); 1135 SDValue N2 = Op.getOperand(2); 1136 SDValue N3 = Op.getOperand(3); 1137 SDValue InFlag = Op.getOperand(4); 1138 assert(N2.getOpcode() == ISD::Constant); 1139 assert(N3.getOpcode() == ISD::Register); 1140 1141 if (!Subtarget->isThumb1Only() && VT == EVT::i32) { 1142 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1143 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1144 // Pattern complexity = 18 cost = 1 size = 0 1145 SDValue CPTmp0; 1146 SDValue CPTmp1; 1147 SDValue CPTmp2; 1148 if (Subtarget->isThumb()) { 1149 if (SelectT2ShifterOperandReg(Op, N1, CPTmp0, CPTmp1)) { 1150 unsigned SOVal = cast<ConstantSDNode>(CPTmp1)->getZExtValue(); 1151 unsigned SOShOp = ARM_AM::getSORegShOp(SOVal); 1152 unsigned Opc = 0; 1153 switch (SOShOp) { 1154 case ARM_AM::lsl: Opc = ARM::t2MOVCClsl; break; 1155 case ARM_AM::lsr: Opc = ARM::t2MOVCClsr; break; 1156 case ARM_AM::asr: Opc = ARM::t2MOVCCasr; break; 1157 case ARM_AM::ror: Opc = ARM::t2MOVCCror; break; 1158 default: 1159 llvm_unreachable("Unknown so_reg opcode!"); 1160 break; 1161 } 1162 SDValue SOShImm = 1163 CurDAG->getTargetConstant(ARM_AM::getSORegOffset(SOVal), EVT::i32); 1164 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1165 cast<ConstantSDNode>(N2)->getZExtValue()), 1166 EVT::i32); 1167 SDValue Ops[] = { N0, CPTmp0, SOShImm, Tmp2, N3, InFlag }; 1168 return CurDAG->SelectNodeTo(Op.getNode(), Opc, EVT::i32,Ops, 6); 1169 } 1170 } else { 1171 if (SelectShifterOperandReg(Op, N1, CPTmp0, CPTmp1, CPTmp2)) { 1172 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1173 cast<ConstantSDNode>(N2)->getZExtValue()), 1174 EVT::i32); 1175 SDValue Ops[] = { N0, CPTmp0, CPTmp1, CPTmp2, Tmp2, N3, InFlag }; 1176 return CurDAG->SelectNodeTo(Op.getNode(), 1177 ARM::MOVCCs, EVT::i32, Ops, 7); 1178 } 1179 } 1180 1181 // Pattern: (ARMcmov:i32 GPR:i32:$false, 1182 // (imm:i32)<<P:Predicate_so_imm>>:$true, 1183 // (imm:i32):$cc) 1184 // Emits: (MOVCCi:i32 GPR:i32:$false, 1185 // (so_imm:i32 (imm:i32):$true), (imm:i32):$cc) 1186 // Pattern complexity = 10 cost = 1 size = 0 1187 if (N3.getOpcode() == ISD::Constant) { 1188 if (Subtarget->isThumb()) { 1189 if (Predicate_t2_so_imm(N3.getNode())) { 1190 SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned) 1191 cast<ConstantSDNode>(N1)->getZExtValue()), 1192 EVT::i32); 1193 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1194 cast<ConstantSDNode>(N2)->getZExtValue()), 1195 EVT::i32); 1196 SDValue Ops[] = { N0, Tmp1, Tmp2, N3, InFlag }; 1197 return CurDAG->SelectNodeTo(Op.getNode(), 1198 ARM::t2MOVCCi, EVT::i32, Ops, 5); 1199 } 1200 } else { 1201 if (Predicate_so_imm(N3.getNode())) { 1202 SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned) 1203 cast<ConstantSDNode>(N1)->getZExtValue()), 1204 EVT::i32); 1205 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1206 cast<ConstantSDNode>(N2)->getZExtValue()), 1207 EVT::i32); 1208 SDValue Ops[] = { N0, Tmp1, Tmp2, N3, InFlag }; 1209 return CurDAG->SelectNodeTo(Op.getNode(), 1210 ARM::MOVCCi, EVT::i32, Ops, 5); 1211 } 1212 } 1213 } 1214 } 1215 1216 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1217 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1218 // Pattern complexity = 6 cost = 1 size = 0 1219 // 1220 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1221 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1222 // Pattern complexity = 6 cost = 11 size = 0 1223 // 1224 // Also FCPYScc and FCPYDcc. 1225 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1226 cast<ConstantSDNode>(N2)->getZExtValue()), 1227 EVT::i32); 1228 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 1229 unsigned Opc = 0; 1230 switch (VT.getSimpleVT()) { 1231 default: assert(false && "Illegal conditional move type!"); 1232 break; 1233 case EVT::i32: 1234 Opc = Subtarget->isThumb() 1235 ? (Subtarget->hasThumb2() ? ARM::t2MOVCCr : ARM::tMOVCCr) 1236 : ARM::MOVCCr; 1237 break; 1238 case EVT::f32: 1239 Opc = ARM::FCPYScc; 1240 break; 1241 case EVT::f64: 1242 Opc = ARM::FCPYDcc; 1243 break; 1244 } 1245 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); 1246 } 1247 case ARMISD::CNEG: { 1248 EVT VT = Op.getValueType(); 1249 SDValue N0 = Op.getOperand(0); 1250 SDValue N1 = Op.getOperand(1); 1251 SDValue N2 = Op.getOperand(2); 1252 SDValue N3 = Op.getOperand(3); 1253 SDValue InFlag = Op.getOperand(4); 1254 assert(N2.getOpcode() == ISD::Constant); 1255 assert(N3.getOpcode() == ISD::Register); 1256 1257 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1258 cast<ConstantSDNode>(N2)->getZExtValue()), 1259 EVT::i32); 1260 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 1261 unsigned Opc = 0; 1262 switch (VT.getSimpleVT()) { 1263 default: assert(false && "Illegal conditional move type!"); 1264 break; 1265 case EVT::f32: 1266 Opc = ARM::FNEGScc; 1267 break; 1268 case EVT::f64: 1269 Opc = ARM::FNEGDcc; 1270 break; 1271 } 1272 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); 1273 } 1274 1275 case ISD::DECLARE: { 1276 SDValue Chain = Op.getOperand(0); 1277 SDValue N1 = Op.getOperand(1); 1278 SDValue N2 = Op.getOperand(2); 1279 FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(N1); 1280 // FIXME: handle VLAs. 1281 if (!FINode) { 1282 ReplaceUses(Op.getValue(0), Chain); 1283 return NULL; 1284 } 1285 if (N2.getOpcode() == ARMISD::PIC_ADD && isa<LoadSDNode>(N2.getOperand(0))) 1286 N2 = N2.getOperand(0); 1287 LoadSDNode *Ld = dyn_cast<LoadSDNode>(N2); 1288 if (!Ld) { 1289 ReplaceUses(Op.getValue(0), Chain); 1290 return NULL; 1291 } 1292 SDValue BasePtr = Ld->getBasePtr(); 1293 assert(BasePtr.getOpcode() == ARMISD::Wrapper && 1294 isa<ConstantPoolSDNode>(BasePtr.getOperand(0)) && 1295 "llvm.dbg.variable should be a constantpool node"); 1296 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(BasePtr.getOperand(0)); 1297 GlobalValue *GV = 0; 1298 if (CP->isMachineConstantPoolEntry()) { 1299 ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)CP->getMachineCPVal(); 1300 GV = ACPV->getGV(); 1301 } else 1302 GV = dyn_cast<GlobalValue>(CP->getConstVal()); 1303 if (!GV) { 1304 ReplaceUses(Op.getValue(0), Chain); 1305 return NULL; 1306 } 1307 1308 SDValue Tmp1 = CurDAG->getTargetFrameIndex(FINode->getIndex(), 1309 TLI.getPointerTy()); 1310 SDValue Tmp2 = CurDAG->getTargetGlobalAddress(GV, TLI.getPointerTy()); 1311 SDValue Ops[] = { Tmp1, Tmp2, Chain }; 1312 return CurDAG->getTargetNode(TargetInstrInfo::DECLARE, dl, 1313 EVT::Other, Ops, 3); 1314 } 1315 1316 case ISD::VECTOR_SHUFFLE: { 1317 EVT VT = Op.getValueType(); 1318 1319 // Match 128-bit splat to VDUPLANEQ. (This could be done with a Pat in 1320 // ARMInstrNEON.td but it is awkward because the shuffle mask needs to be 1321 // transformed first into a lane number and then to both a subregister 1322 // index and an adjusted lane number.) If the source operand is a 1323 // SCALAR_TO_VECTOR, leave it so it will be matched later as a VDUP. 1324 ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N); 1325 if (VT.is128BitVector() && SVOp->isSplat() && 1326 Op.getOperand(0).getOpcode() != ISD::SCALAR_TO_VECTOR && 1327 Op.getOperand(1).getOpcode() == ISD::UNDEF) { 1328 unsigned LaneVal = SVOp->getSplatIndex(); 1329 1330 EVT HalfVT; 1331 unsigned Opc = 0; 1332 switch (VT.getVectorElementType().getSimpleVT()) { 1333 default: llvm_unreachable("unhandled VDUP splat type"); 1334 case EVT::i8: Opc = ARM::VDUPLN8q; HalfVT = EVT::v8i8; break; 1335 case EVT::i16: Opc = ARM::VDUPLN16q; HalfVT = EVT::v4i16; break; 1336 case EVT::i32: Opc = ARM::VDUPLN32q; HalfVT = EVT::v2i32; break; 1337 case EVT::f32: Opc = ARM::VDUPLNfq; HalfVT = EVT::v2f32; break; 1338 } 1339 1340 // The source operand needs to be changed to a subreg of the original 1341 // 128-bit operand, and the lane number needs to be adjusted accordingly. 1342 unsigned NumElts = VT.getVectorNumElements() / 2; 1343 unsigned SRVal = (LaneVal < NumElts ? arm_dsubreg_0 : arm_dsubreg_1); 1344 SDValue SR = CurDAG->getTargetConstant(SRVal, EVT::i32); 1345 SDValue NewLane = CurDAG->getTargetConstant(LaneVal % NumElts, EVT::i32); 1346 SDNode *SubReg = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG, 1347 dl, HalfVT, N->getOperand(0), SR); 1348 return CurDAG->SelectNodeTo(N, Opc, VT, SDValue(SubReg, 0), NewLane); 1349 } 1350 1351 break; 1352 } 1353 1354 case ARMISD::VLD2D: { 1355 SDValue MemAddr, MemUpdate, MemOpc; 1356 if (!SelectAddrMode6(Op, N->getOperand(1), MemAddr, MemUpdate, MemOpc)) 1357 return NULL; 1358 unsigned Opc = 0; 1359 EVT VT = Op.getValueType(); 1360 switch (VT.getSimpleVT()) { 1361 default: llvm_unreachable("unhandled VLD2D type"); 1362 case EVT::v8i8: Opc = ARM::VLD2d8; break; 1363 case EVT::v4i16: Opc = ARM::VLD2d16; break; 1364 case EVT::v2f32: 1365 case EVT::v2i32: Opc = ARM::VLD2d32; break; 1366 } 1367 const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc }; 1368 return CurDAG->getTargetNode(Opc, dl, VT, VT, EVT::Other, Ops, 3); 1369 } 1370 1371 case ARMISD::VLD3D: { 1372 SDValue MemAddr, MemUpdate, MemOpc; 1373 if (!SelectAddrMode6(Op, N->getOperand(1), MemAddr, MemUpdate, MemOpc)) 1374 return NULL; 1375 unsigned Opc = 0; 1376 EVT VT = Op.getValueType(); 1377 switch (VT.getSimpleVT()) { 1378 default: llvm_unreachable("unhandled VLD3D type"); 1379 case EVT::v8i8: Opc = ARM::VLD3d8; break; 1380 case EVT::v4i16: Opc = ARM::VLD3d16; break; 1381 case EVT::v2f32: 1382 case EVT::v2i32: Opc = ARM::VLD3d32; break; 1383 } 1384 const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc }; 1385 return CurDAG->getTargetNode(Opc, dl, VT, VT, VT, EVT::Other, Ops, 3); 1386 } 1387 1388 case ARMISD::VLD4D: { 1389 SDValue MemAddr, MemUpdate, MemOpc; 1390 if (!SelectAddrMode6(Op, N->getOperand(1), MemAddr, MemUpdate, MemOpc)) 1391 return NULL; 1392 unsigned Opc = 0; 1393 EVT VT = Op.getValueType(); 1394 switch (VT.getSimpleVT()) { 1395 default: llvm_unreachable("unhandled VLD4D type"); 1396 case EVT::v8i8: Opc = ARM::VLD4d8; break; 1397 case EVT::v4i16: Opc = ARM::VLD4d16; break; 1398 case EVT::v2f32: 1399 case EVT::v2i32: Opc = ARM::VLD4d32; break; 1400 } 1401 const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc }; 1402 std::vector<EVT> ResTys(4, VT); 1403 ResTys.push_back(EVT::Other); 1404 return CurDAG->getTargetNode(Opc, dl, ResTys, Ops, 3); 1405 } 1406 1407 case ARMISD::VST2D: { 1408 SDValue MemAddr, MemUpdate, MemOpc; 1409 if (!SelectAddrMode6(Op, N->getOperand(1), MemAddr, MemUpdate, MemOpc)) 1410 return NULL; 1411 unsigned Opc = 0; 1412 switch (N->getOperand(2).getValueType().getSimpleVT()) { 1413 default: llvm_unreachable("unhandled VST2D type"); 1414 case EVT::v8i8: Opc = ARM::VST2d8; break; 1415 case EVT::v4i16: Opc = ARM::VST2d16; break; 1416 case EVT::v2f32: 1417 case EVT::v2i32: Opc = ARM::VST2d32; break; 1418 } 1419 const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, 1420 N->getOperand(2), N->getOperand(3) }; 1421 return CurDAG->getTargetNode(Opc, dl, EVT::Other, Ops, 5); 1422 } 1423 1424 case ARMISD::VST3D: { 1425 SDValue MemAddr, MemUpdate, MemOpc; 1426 if (!SelectAddrMode6(Op, N->getOperand(1), MemAddr, MemUpdate, MemOpc)) 1427 return NULL; 1428 unsigned Opc = 0; 1429 switch (N->getOperand(2).getValueType().getSimpleVT()) { 1430 default: llvm_unreachable("unhandled VST3D type"); 1431 case EVT::v8i8: Opc = ARM::VST3d8; break; 1432 case EVT::v4i16: Opc = ARM::VST3d16; break; 1433 case EVT::v2f32: 1434 case EVT::v2i32: Opc = ARM::VST3d32; break; 1435 } 1436 const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, 1437 N->getOperand(2), N->getOperand(3), 1438 N->getOperand(4) }; 1439 return CurDAG->getTargetNode(Opc, dl, EVT::Other, Ops, 6); 1440 } 1441 1442 case ARMISD::VST4D: { 1443 SDValue MemAddr, MemUpdate, MemOpc; 1444 if (!SelectAddrMode6(Op, N->getOperand(1), MemAddr, MemUpdate, MemOpc)) 1445 return NULL; 1446 unsigned Opc = 0; 1447 switch (N->getOperand(2).getValueType().getSimpleVT()) { 1448 default: llvm_unreachable("unhandled VST4D type"); 1449 case EVT::v8i8: Opc = ARM::VST4d8; break; 1450 case EVT::v4i16: Opc = ARM::VST4d16; break; 1451 case EVT::v2f32: 1452 case EVT::v2i32: Opc = ARM::VST4d32; break; 1453 } 1454 const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, 1455 N->getOperand(2), N->getOperand(3), 1456 N->getOperand(4), N->getOperand(5) }; 1457 return CurDAG->getTargetNode(Opc, dl, EVT::Other, Ops, 7); 1458 } 1459 1460 case ISD::INTRINSIC_WO_CHAIN: { 1461 unsigned IntNo = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 1462 EVT VT = N->getValueType(0); 1463 unsigned Opc = 0; 1464 1465 // Match intrinsics that return multiple values. 1466 switch (IntNo) { 1467 default: break; 1468 1469 case Intrinsic::arm_neon_vtrn: 1470 switch (VT.getSimpleVT()) { 1471 default: return NULL; 1472 case EVT::v8i8: Opc = ARM::VTRNd8; break; 1473 case EVT::v4i16: Opc = ARM::VTRNd16; break; 1474 case EVT::v2f32: 1475 case EVT::v2i32: Opc = ARM::VTRNd32; break; 1476 case EVT::v16i8: Opc = ARM::VTRNq8; break; 1477 case EVT::v8i16: Opc = ARM::VTRNq16; break; 1478 case EVT::v4f32: 1479 case EVT::v4i32: Opc = ARM::VTRNq32; break; 1480 } 1481 return CurDAG->getTargetNode(Opc, dl, VT, VT, N->getOperand(1), 1482 N->getOperand(2)); 1483 1484 case Intrinsic::arm_neon_vuzp: 1485 switch (VT.getSimpleVT()) { 1486 default: return NULL; 1487 case EVT::v8i8: Opc = ARM::VUZPd8; break; 1488 case EVT::v4i16: Opc = ARM::VUZPd16; break; 1489 case EVT::v2f32: 1490 case EVT::v2i32: Opc = ARM::VUZPd32; break; 1491 case EVT::v16i8: Opc = ARM::VUZPq8; break; 1492 case EVT::v8i16: Opc = ARM::VUZPq16; break; 1493 case EVT::v4f32: 1494 case EVT::v4i32: Opc = ARM::VUZPq32; break; 1495 } 1496 return CurDAG->getTargetNode(Opc, dl, VT, VT, N->getOperand(1), 1497 N->getOperand(2)); 1498 1499 case Intrinsic::arm_neon_vzip: 1500 switch (VT.getSimpleVT()) { 1501 default: return NULL; 1502 case EVT::v8i8: Opc = ARM::VZIPd8; break; 1503 case EVT::v4i16: Opc = ARM::VZIPd16; break; 1504 case EVT::v2f32: 1505 case EVT::v2i32: Opc = ARM::VZIPd32; break; 1506 case EVT::v16i8: Opc = ARM::VZIPq8; break; 1507 case EVT::v8i16: Opc = ARM::VZIPq16; break; 1508 case EVT::v4f32: 1509 case EVT::v4i32: Opc = ARM::VZIPq32; break; 1510 } 1511 return CurDAG->getTargetNode(Opc, dl, VT, VT, N->getOperand(1), 1512 N->getOperand(2)); 1513 } 1514 break; 1515 } 1516 } 1517 1518 return SelectCode(Op); 1519} 1520 1521bool ARMDAGToDAGISel:: 1522SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 1523 std::vector<SDValue> &OutOps) { 1524 assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); 1525 1526 SDValue Base, Offset, Opc; 1527 if (!SelectAddrMode2(Op, Op, Base, Offset, Opc)) 1528 return true; 1529 1530 OutOps.push_back(Base); 1531 OutOps.push_back(Offset); 1532 OutOps.push_back(Opc); 1533 return false; 1534} 1535 1536/// createARMISelDag - This pass converts a legalized DAG into a 1537/// ARM-specific DAG, ready for instruction scheduling. 1538/// 1539FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM) { 1540 return new ARMDAGToDAGISel(TM); 1541} 1542