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/CodeGen/MachineFrameInfo.h" 25 #include "llvm/CodeGen/MachineFunction.h" 26 #include "llvm/CodeGen/MachineInstrBuilder.h" 27 #include "llvm/CodeGen/SelectionDAG.h" 28 #include "llvm/CodeGen/SelectionDAGISel.h" 29 #include "llvm/Target/TargetLowering.h" 30 #include "llvm/Target/TargetOptions.h" 31 #include "llvm/Support/Compiler.h" 32 #include "llvm/Support/Debug.h" 33 using namespace llvm; 34 35 static const unsigned arm_dsubreg_0 = 5; 36 static const unsigned arm_dsubreg_1 = 6; 37 38 //===--------------------------------------------------------------------===// 39 /// ARMDAGToDAGISel - ARM specific code to select ARM machine 40 /// instructions for SelectionDAG operations. 41 /// 42 namespace { 43 class ARMDAGToDAGISel : public SelectionDAGISel { 44 ARMBaseTargetMachine &TM; 45 46 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 47 /// make the right decision when generating code for different targets. 48 const ARMSubtarget *Subtarget; 49 50 public: 51 explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm) 52 : SelectionDAGISel(tm), TM(tm), 53 Subtarget(&TM.getSubtarget<ARMSubtarget>()) { 54 } 55 56 virtual const char *getPassName() const { 57 return "ARM Instruction Selection"; 58 } 59 60 /// getI32Imm - Return a target constant with the specified value, of type i32. 61 inline SDValue getI32Imm(unsigned Imm) { 62 return CurDAG->getTargetConstant(Imm, MVT::i32); 63 } 64 65 SDNode *Select(SDValue Op); 66 virtual void InstructionSelect(); 67 bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A, 68 SDValue &B, SDValue &C); 69 bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base, 70 SDValue &Offset, SDValue &Opc); 71 bool SelectAddrMode2Offset(SDValue Op, SDValue N, 72 SDValue &Offset, SDValue &Opc); 73 bool SelectAddrMode3(SDValue Op, SDValue N, SDValue &Base, 74 SDValue &Offset, SDValue &Opc); 75 bool SelectAddrMode3Offset(SDValue Op, SDValue N, 76 SDValue &Offset, SDValue &Opc); 77 bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base, 78 SDValue &Offset); 79 bool SelectAddrMode6(SDValue Op, SDValue N, SDValue &Addr, SDValue &Update, 80 SDValue &Opc); 81 82 bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset, 83 SDValue &Label); 84 85 bool SelectThumbAddrModeRR(SDValue Op, SDValue N, SDValue &Base, 86 SDValue &Offset); 87 bool SelectThumbAddrModeRI5(SDValue Op, SDValue N, unsigned Scale, 88 SDValue &Base, SDValue &OffImm, 89 SDValue &Offset); 90 bool SelectThumbAddrModeS1(SDValue Op, SDValue N, SDValue &Base, 91 SDValue &OffImm, SDValue &Offset); 92 bool SelectThumbAddrModeS2(SDValue Op, SDValue N, SDValue &Base, 93 SDValue &OffImm, SDValue &Offset); 94 bool SelectThumbAddrModeS4(SDValue Op, SDValue N, SDValue &Base, 95 SDValue &OffImm, SDValue &Offset); 96 bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base, 97 SDValue &OffImm); 98 99 bool SelectT2ShifterOperandReg(SDValue Op, SDValue N, 100 SDValue &BaseReg, SDValue &Opc); 101 bool SelectT2AddrModeImm12(SDValue Op, SDValue N, SDValue &Base, 102 SDValue &OffImm); 103 bool SelectT2AddrModeImm8(SDValue Op, SDValue N, SDValue &Base, 104 SDValue &OffImm); 105 bool SelectT2AddrModeImm8Offset(SDValue Op, SDValue N, 106 SDValue &OffImm); 107 bool SelectT2AddrModeImm8s4(SDValue Op, SDValue N, SDValue &Base, 108 SDValue &OffImm); 109 bool SelectT2AddrModeSoReg(SDValue Op, SDValue N, SDValue &Base, 110 SDValue &OffReg, SDValue &ShImm); 111 112 // Include the pieces autogenerated from the target description. 113 #include "ARMGenDAGISel.inc" 114 115 private: 116 /// SelectARMIndexedLoad - Indexed (pre/post inc/dec) load matching code for 117 /// ARM. 118 SDNode *SelectARMIndexedLoad(SDValue Op); 119 SDNode *SelectT2IndexedLoad(SDValue Op); 120 121 122 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 123 /// inline asm expressions. 124 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 125 char ConstraintCode, 126 std::vector<SDValue> &OutOps); 127 }; 128 } 129 130 void ARMDAGToDAGISel::InstructionSelect() { 131 DEBUG(BB->dump()); 132 133 SelectRoot(*CurDAG); 134 CurDAG->RemoveDeadNodes(); 135 } 136 137 bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op, 138 SDValue N, 139 SDValue &BaseReg, 140 SDValue &ShReg, 141 SDValue &Opc) { 142 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 143 144 // Don't match base register only case. That is matched to a separate 145 // lower complexity pattern with explicit register operand. 146 if (ShOpcVal == ARM_AM::no_shift) return false; 147 148 BaseReg = N.getOperand(0); 149 unsigned ShImmVal = 0; 150 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 151 ShReg = CurDAG->getRegister(0, MVT::i32); 152 ShImmVal = RHS->getZExtValue() & 31; 153 } else { 154 ShReg = N.getOperand(1); 155 } 156 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 157 MVT::i32); 158 return true; 159 } 160 161 bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N, 162 SDValue &Base, SDValue &Offset, 163 SDValue &Opc) { 164 if (N.getOpcode() == ISD::MUL) { 165 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 166 // X * [3,5,9] -> X + X * [2,4,8] etc. 167 int RHSC = (int)RHS->getZExtValue(); 168 if (RHSC & 1) { 169 RHSC = RHSC & ~1; 170 ARM_AM::AddrOpc AddSub = ARM_AM::add; 171 if (RHSC < 0) { 172 AddSub = ARM_AM::sub; 173 RHSC = - RHSC; 174 } 175 if (isPowerOf2_32(RHSC)) { 176 unsigned ShAmt = Log2_32(RHSC); 177 Base = Offset = N.getOperand(0); 178 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, 179 ARM_AM::lsl), 180 MVT::i32); 181 return true; 182 } 183 } 184 } 185 } 186 187 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 188 Base = N; 189 if (N.getOpcode() == ISD::FrameIndex) { 190 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 191 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 192 } else if (N.getOpcode() == ARMISD::Wrapper) { 193 Base = N.getOperand(0); 194 } 195 Offset = CurDAG->getRegister(0, MVT::i32); 196 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, 197 ARM_AM::no_shift), 198 MVT::i32); 199 return true; 200 } 201 202 // Match simple R +/- imm12 operands. 203 if (N.getOpcode() == ISD::ADD) 204 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 205 int RHSC = (int)RHS->getZExtValue(); 206 if ((RHSC >= 0 && RHSC < 0x1000) || 207 (RHSC < 0 && RHSC > -0x1000)) { // 12 bits. 208 Base = N.getOperand(0); 209 if (Base.getOpcode() == ISD::FrameIndex) { 210 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 211 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 212 } 213 Offset = CurDAG->getRegister(0, MVT::i32); 214 215 ARM_AM::AddrOpc AddSub = ARM_AM::add; 216 if (RHSC < 0) { 217 AddSub = ARM_AM::sub; 218 RHSC = - RHSC; 219 } 220 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC, 221 ARM_AM::no_shift), 222 MVT::i32); 223 return true; 224 } 225 } 226 227 // Otherwise this is R +/- [possibly shifted] R 228 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub; 229 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1)); 230 unsigned ShAmt = 0; 231 232 Base = N.getOperand(0); 233 Offset = N.getOperand(1); 234 235 if (ShOpcVal != ARM_AM::no_shift) { 236 // Check to see if the RHS of the shift is a constant, if not, we can't fold 237 // it. 238 if (ConstantSDNode *Sh = 239 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) { 240 ShAmt = Sh->getZExtValue(); 241 Offset = N.getOperand(1).getOperand(0); 242 } else { 243 ShOpcVal = ARM_AM::no_shift; 244 } 245 } 246 247 // Try matching (R shl C) + (R). 248 if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) { 249 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0)); 250 if (ShOpcVal != ARM_AM::no_shift) { 251 // Check to see if the RHS of the shift is a constant, if not, we can't 252 // fold it. 253 if (ConstantSDNode *Sh = 254 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) { 255 ShAmt = Sh->getZExtValue(); 256 Offset = N.getOperand(0).getOperand(0); 257 Base = N.getOperand(1); 258 } else { 259 ShOpcVal = ARM_AM::no_shift; 260 } 261 } 262 } 263 264 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 265 MVT::i32); 266 return true; 267 } 268 269 bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDValue Op, SDValue N, 270 SDValue &Offset, SDValue &Opc) { 271 unsigned Opcode = Op.getOpcode(); 272 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 273 ? cast<LoadSDNode>(Op)->getAddressingMode() 274 : cast<StoreSDNode>(Op)->getAddressingMode(); 275 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 276 ? ARM_AM::add : ARM_AM::sub; 277 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 278 int Val = (int)C->getZExtValue(); 279 if (Val >= 0 && Val < 0x1000) { // 12 bits. 280 Offset = CurDAG->getRegister(0, MVT::i32); 281 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, 282 ARM_AM::no_shift), 283 MVT::i32); 284 return true; 285 } 286 } 287 288 Offset = N; 289 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 290 unsigned ShAmt = 0; 291 if (ShOpcVal != ARM_AM::no_shift) { 292 // Check to see if the RHS of the shift is a constant, if not, we can't fold 293 // it. 294 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 295 ShAmt = Sh->getZExtValue(); 296 Offset = N.getOperand(0); 297 } else { 298 ShOpcVal = ARM_AM::no_shift; 299 } 300 } 301 302 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 303 MVT::i32); 304 return true; 305 } 306 307 308 bool ARMDAGToDAGISel::SelectAddrMode3(SDValue Op, SDValue N, 309 SDValue &Base, SDValue &Offset, 310 SDValue &Opc) { 311 if (N.getOpcode() == ISD::SUB) { 312 // X - C is canonicalize to X + -C, no need to handle it here. 313 Base = N.getOperand(0); 314 Offset = N.getOperand(1); 315 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32); 316 return true; 317 } 318 319 if (N.getOpcode() != ISD::ADD) { 320 Base = N; 321 if (N.getOpcode() == ISD::FrameIndex) { 322 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 323 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 324 } 325 Offset = CurDAG->getRegister(0, MVT::i32); 326 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32); 327 return true; 328 } 329 330 // If the RHS is +/- imm8, fold into addr mode. 331 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 332 int RHSC = (int)RHS->getZExtValue(); 333 if ((RHSC >= 0 && RHSC < 256) || 334 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 335 Base = N.getOperand(0); 336 if (Base.getOpcode() == ISD::FrameIndex) { 337 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 338 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 339 } 340 Offset = CurDAG->getRegister(0, MVT::i32); 341 342 ARM_AM::AddrOpc AddSub = ARM_AM::add; 343 if (RHSC < 0) { 344 AddSub = ARM_AM::sub; 345 RHSC = - RHSC; 346 } 347 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32); 348 return true; 349 } 350 } 351 352 Base = N.getOperand(0); 353 Offset = N.getOperand(1); 354 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32); 355 return true; 356 } 357 358 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N, 359 SDValue &Offset, SDValue &Opc) { 360 unsigned Opcode = Op.getOpcode(); 361 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 362 ? cast<LoadSDNode>(Op)->getAddressingMode() 363 : cast<StoreSDNode>(Op)->getAddressingMode(); 364 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 365 ? ARM_AM::add : ARM_AM::sub; 366 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 367 int Val = (int)C->getZExtValue(); 368 if (Val >= 0 && Val < 256) { 369 Offset = CurDAG->getRegister(0, MVT::i32); 370 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32); 371 return true; 372 } 373 } 374 375 Offset = N; 376 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32); 377 return true; 378 } 379 380 381 bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N, 382 SDValue &Base, SDValue &Offset) { 383 if (N.getOpcode() != ISD::ADD) { 384 Base = N; 385 if (N.getOpcode() == ISD::FrameIndex) { 386 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 387 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 388 } else if (N.getOpcode() == ARMISD::Wrapper) { 389 Base = N.getOperand(0); 390 } 391 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 392 MVT::i32); 393 return true; 394 } 395 396 // If the RHS is +/- imm8, fold into addr mode. 397 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 398 int RHSC = (int)RHS->getZExtValue(); 399 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied by 4. 400 RHSC >>= 2; 401 if ((RHSC >= 0 && RHSC < 256) || 402 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 403 Base = N.getOperand(0); 404 if (Base.getOpcode() == ISD::FrameIndex) { 405 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 406 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 407 } 408 409 ARM_AM::AddrOpc AddSub = ARM_AM::add; 410 if (RHSC < 0) { 411 AddSub = ARM_AM::sub; 412 RHSC = - RHSC; 413 } 414 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC), 415 MVT::i32); 416 return true; 417 } 418 } 419 } 420 421 Base = N; 422 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 423 MVT::i32); 424 return true; 425 } 426 427 bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N, 428 SDValue &Addr, SDValue &Update, 429 SDValue &Opc) { 430 Addr = N; 431 // The optional writeback is handled in ARMLoadStoreOpt. 432 Update = CurDAG->getRegister(0, MVT::i32); 433 Opc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(false), MVT::i32); 434 return true; 435 } 436 437 bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N, 438 SDValue &Offset, SDValue &Label) { 439 if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { 440 Offset = N.getOperand(0); 441 SDValue N1 = N.getOperand(1); 442 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(), 443 MVT::i32); 444 return true; 445 } 446 return false; 447 } 448 449 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op, SDValue N, 450 SDValue &Base, SDValue &Offset){ 451 // FIXME dl should come from the parent load or store, not the address 452 DebugLoc dl = Op.getDebugLoc(); 453 if (N.getOpcode() != ISD::ADD) { 454 Base = N; 455 // We must materialize a zero in a reg! Returning a constant here 456 // wouldn't work without additional code to position the node within 457 // ISel's topological ordering in a place where ISel will process it 458 // normally. Instead, just explicitly issue a tMOVri8 node! 459 Offset = SDValue(CurDAG->getTargetNode(ARM::tMOVi8, dl, MVT::i32, 460 CurDAG->getTargetConstant(0, MVT::i32)), 0); 461 return true; 462 } 463 464 Base = N.getOperand(0); 465 Offset = N.getOperand(1); 466 return true; 467 } 468 469 bool 470 ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op, SDValue N, 471 unsigned Scale, SDValue &Base, 472 SDValue &OffImm, SDValue &Offset) { 473 if (Scale == 4) { 474 SDValue TmpBase, TmpOffImm; 475 if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm)) 476 return false; // We want to select tLDRspi / tSTRspi instead. 477 if (N.getOpcode() == ARMISD::Wrapper && 478 N.getOperand(0).getOpcode() == ISD::TargetConstantPool) 479 return false; // We want to select tLDRpci instead. 480 } 481 482 if (N.getOpcode() != ISD::ADD) { 483 Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N; 484 Offset = CurDAG->getRegister(0, MVT::i32); 485 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 486 return true; 487 } 488 489 // Thumb does not have [sp, r] address mode. 490 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 491 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1)); 492 if ((LHSR && LHSR->getReg() == ARM::SP) || 493 (RHSR && RHSR->getReg() == ARM::SP)) { 494 Base = N; 495 Offset = CurDAG->getRegister(0, MVT::i32); 496 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 497 return true; 498 } 499 500 // If the RHS is + imm5 * scale, fold into addr mode. 501 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 502 int RHSC = (int)RHS->getZExtValue(); 503 if ((RHSC & (Scale-1)) == 0) { // The constant is implicitly multiplied. 504 RHSC /= Scale; 505 if (RHSC >= 0 && RHSC < 32) { 506 Base = N.getOperand(0); 507 Offset = CurDAG->getRegister(0, MVT::i32); 508 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 509 return true; 510 } 511 } 512 } 513 514 Base = N.getOperand(0); 515 Offset = N.getOperand(1); 516 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 517 return true; 518 } 519 520 bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue Op, SDValue N, 521 SDValue &Base, SDValue &OffImm, 522 SDValue &Offset) { 523 return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset); 524 } 525 526 bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue Op, SDValue N, 527 SDValue &Base, SDValue &OffImm, 528 SDValue &Offset) { 529 return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset); 530 } 531 532 bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue Op, SDValue N, 533 SDValue &Base, SDValue &OffImm, 534 SDValue &Offset) { 535 return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset); 536 } 537 538 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N, 539 SDValue &Base, SDValue &OffImm) { 540 if (N.getOpcode() == ISD::FrameIndex) { 541 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 542 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 543 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 544 return true; 545 } 546 547 if (N.getOpcode() != ISD::ADD) 548 return false; 549 550 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 551 if (N.getOperand(0).getOpcode() == ISD::FrameIndex || 552 (LHSR && LHSR->getReg() == ARM::SP)) { 553 // If the RHS is + imm8 * scale, fold into addr mode. 554 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 555 int RHSC = (int)RHS->getZExtValue(); 556 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied. 557 RHSC >>= 2; 558 if (RHSC >= 0 && RHSC < 256) { 559 Base = N.getOperand(0); 560 if (Base.getOpcode() == ISD::FrameIndex) { 561 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 562 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 563 } 564 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 565 return true; 566 } 567 } 568 } 569 } 570 571 return false; 572 } 573 574 bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue Op, SDValue N, 575 SDValue &BaseReg, 576 SDValue &Opc) { 577 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 578 579 // Don't match base register only case. That is matched to a separate 580 // lower complexity pattern with explicit register operand. 581 if (ShOpcVal == ARM_AM::no_shift) return false; 582 583 BaseReg = N.getOperand(0); 584 unsigned ShImmVal = 0; 585 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 586 ShImmVal = RHS->getZExtValue() & 31; 587 Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal)); 588 return true; 589 } 590 591 return false; 592 } 593 594 bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N, 595 SDValue &Base, SDValue &OffImm) { 596 // Match simple R + imm12 operands. 597 if (N.getOpcode() != ISD::ADD) 598 return false; 599 600 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 601 int RHSC = (int)RHS->getZExtValue(); 602 if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits. 603 Base = N.getOperand(0); 604 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 605 return true; 606 } 607 } 608 609 return false; 610 } 611 612 bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue Op, SDValue N, 613 SDValue &Base, SDValue &OffImm) { 614 if (N.getOpcode() == ISD::ADD) { 615 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 616 int RHSC = (int)RHS->getZExtValue(); 617 if (RHSC < 0 && RHSC > -0x100) { // 8 bits. 618 Base = N.getOperand(0); 619 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 620 return true; 621 } 622 } 623 } else if (N.getOpcode() == ISD::SUB) { 624 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 625 int RHSC = (int)RHS->getZExtValue(); 626 if (RHSC >= 0 && RHSC < 0x100) { // 8 bits. 627 Base = N.getOperand(0); 628 OffImm = CurDAG->getTargetConstant(-RHSC, MVT::i32); 629 return true; 630 } 631 } 632 } 633 634 return false; 635 } 636 637 bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDValue Op, SDValue N, 638 SDValue &OffImm){ 639 unsigned Opcode = Op.getOpcode(); 640 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 641 ? cast<LoadSDNode>(Op)->getAddressingMode() 642 : cast<StoreSDNode>(Op)->getAddressingMode(); 643 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N)) { 644 int RHSC = (int)RHS->getZExtValue(); 645 if (RHSC >= 0 && RHSC < 0x100) { // 8 bits. 646 OffImm = (AM == ISD::PRE_INC) 647 ? CurDAG->getTargetConstant(RHSC, MVT::i32) 648 : CurDAG->getTargetConstant(-RHSC, MVT::i32); 649 return true; 650 } 651 } 652 653 return false; 654 } 655 656 bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDValue Op, SDValue N, 657 SDValue &Base, SDValue &OffImm) { 658 if (N.getOpcode() == ISD::ADD) { 659 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 660 int RHSC = (int)RHS->getZExtValue(); 661 if (((RHSC & 0x3) == 0) && (RHSC < 0 && RHSC > -0x400)) { // 8 bits. 662 Base = N.getOperand(0); 663 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 664 return true; 665 } 666 } 667 } else if (N.getOpcode() == ISD::SUB) { 668 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 669 int RHSC = (int)RHS->getZExtValue(); 670 if (((RHSC & 0x3) == 0) && (RHSC >= 0 && RHSC < 0x400)) { // 8 bits. 671 Base = N.getOperand(0); 672 OffImm = CurDAG->getTargetConstant(-RHSC, MVT::i32); 673 return true; 674 } 675 } 676 } 677 678 return false; 679 } 680 681 bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue Op, SDValue N, 682 SDValue &Base, 683 SDValue &OffReg, SDValue &ShImm) { 684 // Base only. 685 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 686 Base = N; 687 if (N.getOpcode() == ISD::FrameIndex) { 688 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 689 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 690 } else if (N.getOpcode() == ARMISD::Wrapper) { 691 Base = N.getOperand(0); 692 if (Base.getOpcode() == ISD::TargetConstantPool) 693 return false; // We want to select t2LDRpci instead. 694 } 695 OffReg = CurDAG->getRegister(0, MVT::i32); 696 ShImm = CurDAG->getTargetConstant(0, MVT::i32); 697 return true; 698 } 699 700 // Look for (R + R) or (R + (R << [1,2,3])). 701 unsigned ShAmt = 0; 702 Base = N.getOperand(0); 703 OffReg = N.getOperand(1); 704 705 // Swap if it is ((R << c) + R). 706 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg); 707 if (ShOpcVal != ARM_AM::lsl) { 708 ShOpcVal = ARM_AM::getShiftOpcForNode(Base); 709 if (ShOpcVal == ARM_AM::lsl) 710 std::swap(Base, OffReg); 711 } 712 713 if (ShOpcVal == ARM_AM::lsl) { 714 // Check to see if the RHS of the shift is a constant, if not, we can't fold 715 // it. 716 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(OffReg.getOperand(1))) { 717 ShAmt = Sh->getZExtValue(); 718 if (ShAmt >= 4) { 719 ShAmt = 0; 720 ShOpcVal = ARM_AM::no_shift; 721 } else 722 OffReg = OffReg.getOperand(0); 723 } else { 724 ShOpcVal = ARM_AM::no_shift; 725 } 726 } else if (SelectT2AddrModeImm12(Op, N, Base, ShImm) || 727 SelectT2AddrModeImm8 (Op, N, Base, ShImm)) 728 // Don't match if it's possible to match to one of the r +/- imm cases. 729 return false; 730 731 ShImm = CurDAG->getTargetConstant(ShAmt, MVT::i32); 732 733 return true; 734 } 735 736 //===--------------------------------------------------------------------===// 737 738 /// getAL - Returns a ARMCC::AL immediate node. 739 static inline SDValue getAL(SelectionDAG *CurDAG) { 740 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32); 741 } 742 743 SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) { 744 LoadSDNode *LD = cast<LoadSDNode>(Op); 745 ISD::MemIndexedMode AM = LD->getAddressingMode(); 746 if (AM == ISD::UNINDEXED) 747 return NULL; 748 749 MVT LoadedVT = LD->getMemoryVT(); 750 SDValue Offset, AMOpc; 751 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 752 unsigned Opcode = 0; 753 bool Match = false; 754 if (LoadedVT == MVT::i32 && 755 SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { 756 Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST; 757 Match = true; 758 } else if (LoadedVT == MVT::i16 && 759 SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { 760 Match = true; 761 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) 762 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) 763 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); 764 } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) { 765 if (LD->getExtensionType() == ISD::SEXTLOAD) { 766 if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { 767 Match = true; 768 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; 769 } 770 } else { 771 if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { 772 Match = true; 773 Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST; 774 } 775 } 776 } 777 778 if (Match) { 779 SDValue Chain = LD->getChain(); 780 SDValue Base = LD->getBasePtr(); 781 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), 782 CurDAG->getRegister(0, MVT::i32), Chain }; 783 return CurDAG->getTargetNode(Opcode, Op.getDebugLoc(), MVT::i32, MVT::i32, 784 MVT::Other, Ops, 6); 785 } 786 787 return NULL; 788 } 789 790 SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDValue Op) { 791 LoadSDNode *LD = cast<LoadSDNode>(Op); 792 ISD::MemIndexedMode AM = LD->getAddressingMode(); 793 if (AM == ISD::UNINDEXED) 794 return NULL; 795 796 MVT LoadedVT = LD->getMemoryVT(); 797 bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD; 798 SDValue Offset; 799 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 800 unsigned Opcode = 0; 801 bool Match = false; 802 if (SelectT2AddrModeImm8Offset(Op, LD->getOffset(), Offset)) { 803 switch (LoadedVT.getSimpleVT()) { 804 case MVT::i32: 805 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST; 806 break; 807 case MVT::i16: 808 if (isSExtLd) 809 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST; 810 else 811 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST; 812 break; 813 case MVT::i8: 814 case MVT::i1: 815 if (isSExtLd) 816 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST; 817 else 818 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST; 819 break; 820 default: 821 return NULL; 822 } 823 Match = true; 824 } 825 826 if (Match) { 827 SDValue Chain = LD->getChain(); 828 SDValue Base = LD->getBasePtr(); 829 SDValue Ops[]= { Base, Offset, getAL(CurDAG), 830 CurDAG->getRegister(0, MVT::i32), Chain }; 831 return CurDAG->getTargetNode(Opcode, Op.getDebugLoc(), MVT::i32, MVT::i32, 832 MVT::Other, Ops, 5); 833 } 834 835 return NULL; 836 } 837 838 839 SDNode *ARMDAGToDAGISel::Select(SDValue Op) { 840 SDNode *N = Op.getNode(); 841 DebugLoc dl = N->getDebugLoc(); 842 843 if (N->isMachineOpcode()) 844 return NULL; // Already selected. 845 846 switch (N->getOpcode()) { 847 default: break; 848 case ISD::Constant: { 849 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 850 bool UseCP = true; 851 if (Subtarget->isThumb()) { 852 if (Subtarget->hasThumb2()) 853 // Thumb2 has the MOVT instruction, so all immediates can 854 // be done with MOV + MOVT, at worst. 855 UseCP = 0; 856 else 857 UseCP = (Val > 255 && // MOV 858 ~Val > 255 && // MOV + MVN 859 !ARM_AM::isThumbImmShiftedVal(Val)); // MOV + LSL 860 } else 861 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV 862 ARM_AM::getSOImmVal(~Val) == -1 && // MVN 863 !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs. 864 if (UseCP) { 865 SDValue CPIdx = 866 CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val), 867 TLI.getPointerTy()); 868 869 SDNode *ResNode; 870 if (Subtarget->isThumb()) 871 ResNode = CurDAG->getTargetNode(ARM::tLDRcp, dl, MVT::i32, MVT::Other, 872 CPIdx, CurDAG->getEntryNode()); 873 else { 874 SDValue Ops[] = { 875 CPIdx, 876 CurDAG->getRegister(0, MVT::i32), 877 CurDAG->getTargetConstant(0, MVT::i32), 878 getAL(CurDAG), 879 CurDAG->getRegister(0, MVT::i32), 880 CurDAG->getEntryNode() 881 }; 882 ResNode=CurDAG->getTargetNode(ARM::LDRcp, dl, MVT::i32, MVT::Other, 883 Ops, 6); 884 } 885 ReplaceUses(Op, SDValue(ResNode, 0)); 886 return NULL; 887 } 888 889 // Other cases are autogenerated. 890 break; 891 } 892 case ISD::FrameIndex: { 893 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. 894 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 895 SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 896 if (Subtarget->isThumb()) { 897 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI, 898 CurDAG->getTargetConstant(0, MVT::i32)); 899 } else { 900 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), 901 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 902 CurDAG->getRegister(0, MVT::i32) }; 903 return CurDAG->SelectNodeTo(N, ARM::ADDri, MVT::i32, Ops, 5); 904 } 905 } 906 case ISD::ADD: { 907 if (!Subtarget->isThumb()) 908 break; 909 // Select add sp, c to tADDhirr. 910 SDValue N0 = Op.getOperand(0); 911 SDValue N1 = Op.getOperand(1); 912 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(Op.getOperand(0)); 913 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(Op.getOperand(1)); 914 if (LHSR && LHSR->getReg() == ARM::SP) { 915 std::swap(N0, N1); 916 std::swap(LHSR, RHSR); 917 } 918 if (RHSR && RHSR->getReg() == ARM::SP) { 919 SDValue Val = SDValue(CurDAG->getTargetNode(ARM::tMOVlor2hir, dl, 920 Op.getValueType(), N0, N0), 0); 921 return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType(), Val, N1); 922 } 923 break; 924 } 925 case ISD::MUL: 926 if (Subtarget->isThumb()) 927 break; 928 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { 929 unsigned RHSV = C->getZExtValue(); 930 if (!RHSV) break; 931 if (isPowerOf2_32(RHSV-1)) { // 2^n+1? 932 SDValue V = Op.getOperand(0); 933 unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1)); 934 SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32), 935 CurDAG->getTargetConstant(ShImm, MVT::i32), 936 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 937 CurDAG->getRegister(0, MVT::i32) }; 938 return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7); 939 } 940 if (isPowerOf2_32(RHSV+1)) { // 2^n-1? 941 SDValue V = Op.getOperand(0); 942 unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV+1)); 943 SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32), 944 CurDAG->getTargetConstant(ShImm, MVT::i32), 945 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 946 CurDAG->getRegister(0, MVT::i32) }; 947 return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7); 948 } 949 } 950 break; 951 case ARMISD::FMRRD: 952 return CurDAG->getTargetNode(ARM::FMRRD, dl, MVT::i32, MVT::i32, 953 Op.getOperand(0), getAL(CurDAG), 954 CurDAG->getRegister(0, MVT::i32)); 955 case ISD::UMUL_LOHI: { 956 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 957 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 958 CurDAG->getRegister(0, MVT::i32) }; 959 return CurDAG->getTargetNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5); 960 } 961 case ISD::SMUL_LOHI: { 962 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 963 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 964 CurDAG->getRegister(0, MVT::i32) }; 965 return CurDAG->getTargetNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5); 966 } 967 case ISD::LOAD: { 968 SDNode *ResNode = 0; 969 if (Subtarget->isThumb2()) 970 ResNode = SelectT2IndexedLoad(Op); 971 else 972 ResNode = SelectARMIndexedLoad(Op); 973 if (ResNode) 974 return ResNode; 975 // Other cases are autogenerated. 976 break; 977 } 978 case ARMISD::BRCOND: { 979 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 980 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc) 981 // Pattern complexity = 6 cost = 1 size = 0 982 983 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 984 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc) 985 // Pattern complexity = 6 cost = 1 size = 0 986 987 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 988 // Emits: (t2Bcc:void (bb:Other):$dst, (imm:i32):$cc) 989 // Pattern complexity = 6 cost = 1 size = 0 990 991 unsigned Opc = Subtarget->isThumb() ? 992 ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; 993 SDValue Chain = Op.getOperand(0); 994 SDValue N1 = Op.getOperand(1); 995 SDValue N2 = Op.getOperand(2); 996 SDValue N3 = Op.getOperand(3); 997 SDValue InFlag = Op.getOperand(4); 998 assert(N1.getOpcode() == ISD::BasicBlock); 999 assert(N2.getOpcode() == ISD::Constant); 1000 assert(N3.getOpcode() == ISD::Register); 1001 1002 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1003 cast<ConstantSDNode>(N2)->getZExtValue()), 1004 MVT::i32); 1005 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; 1006 SDNode *ResNode = CurDAG->getTargetNode(Opc, dl, MVT::Other, 1007 MVT::Flag, Ops, 5); 1008 Chain = SDValue(ResNode, 0); 1009 if (Op.getNode()->getNumValues() == 2) { 1010 InFlag = SDValue(ResNode, 1); 1011 ReplaceUses(SDValue(Op.getNode(), 1), InFlag); 1012 } 1013 ReplaceUses(SDValue(Op.getNode(), 0), SDValue(Chain.getNode(), Chain.getResNo())); 1014 return NULL; 1015 } 1016 case ARMISD::CMOV: { 1017 bool isThumb = Subtarget->isThumb(); 1018 MVT VT = Op.getValueType(); 1019 SDValue N0 = Op.getOperand(0); 1020 SDValue N1 = Op.getOperand(1); 1021 SDValue N2 = Op.getOperand(2); 1022 SDValue N3 = Op.getOperand(3); 1023 SDValue InFlag = Op.getOperand(4); 1024 assert(N2.getOpcode() == ISD::Constant); 1025 assert(N3.getOpcode() == ISD::Register); 1026 1027 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1028 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1029 // Pattern complexity = 18 cost = 1 size = 0 1030 SDValue CPTmp0; 1031 SDValue CPTmp1; 1032 SDValue CPTmp2; 1033 if (!isThumb && VT == MVT::i32 && 1034 SelectShifterOperandReg(Op, N1, CPTmp0, CPTmp1, CPTmp2)) { 1035 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1036 cast<ConstantSDNode>(N2)->getZExtValue()), 1037 MVT::i32); 1038 SDValue Ops[] = { N0, CPTmp0, CPTmp1, CPTmp2, Tmp2, N3, InFlag }; 1039 return CurDAG->SelectNodeTo(Op.getNode(), ARM::MOVCCs, MVT::i32, Ops, 7); 1040 } 1041 1042 // Pattern: (ARMcmov:i32 GPR:i32:$false, 1043 // (imm:i32)<<P:Predicate_so_imm>><<X:so_imm_XFORM>>:$true, 1044 // (imm:i32):$cc) 1045 // Emits: (MOVCCi:i32 GPR:i32:$false, 1046 // (so_imm_XFORM:i32 (imm:i32):$true), (imm:i32):$cc) 1047 // Pattern complexity = 10 cost = 1 size = 0 1048 if (VT == MVT::i32 && 1049 N3.getOpcode() == ISD::Constant && 1050 Predicate_so_imm(N3.getNode())) { 1051 SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned) 1052 cast<ConstantSDNode>(N1)->getZExtValue()), 1053 MVT::i32); 1054 Tmp1 = Transform_so_imm_XFORM(Tmp1.getNode()); 1055 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1056 cast<ConstantSDNode>(N2)->getZExtValue()), 1057 MVT::i32); 1058 SDValue Ops[] = { N0, Tmp1, Tmp2, N3, InFlag }; 1059 return CurDAG->SelectNodeTo(Op.getNode(), ARM::MOVCCi, MVT::i32, Ops, 5); 1060 } 1061 1062 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1063 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1064 // Pattern complexity = 6 cost = 1 size = 0 1065 // 1066 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1067 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1068 // Pattern complexity = 6 cost = 11 size = 0 1069 // 1070 // Also FCPYScc and FCPYDcc. 1071 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1072 cast<ConstantSDNode>(N2)->getZExtValue()), 1073 MVT::i32); 1074 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 1075 unsigned Opc = 0; 1076 switch (VT.getSimpleVT()) { 1077 default: assert(false && "Illegal conditional move type!"); 1078 break; 1079 case MVT::i32: 1080 Opc = isThumb ? ARM::tMOVCCr : ARM::MOVCCr; 1081 break; 1082 case MVT::f32: 1083 Opc = ARM::FCPYScc; 1084 break; 1085 case MVT::f64: 1086 Opc = ARM::FCPYDcc; 1087 break; 1088 } 1089 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); 1090 } 1091 case ARMISD::CNEG: { 1092 MVT VT = Op.getValueType(); 1093 SDValue N0 = Op.getOperand(0); 1094 SDValue N1 = Op.getOperand(1); 1095 SDValue N2 = Op.getOperand(2); 1096 SDValue N3 = Op.getOperand(3); 1097 SDValue InFlag = Op.getOperand(4); 1098 assert(N2.getOpcode() == ISD::Constant); 1099 assert(N3.getOpcode() == ISD::Register); 1100 1101 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1102 cast<ConstantSDNode>(N2)->getZExtValue()), 1103 MVT::i32); 1104 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 1105 unsigned Opc = 0; 1106 switch (VT.getSimpleVT()) { 1107 default: assert(false && "Illegal conditional move type!"); 1108 break; 1109 case MVT::f32: 1110 Opc = ARM::FNEGScc; 1111 break; 1112 case MVT::f64: 1113 Opc = ARM::FNEGDcc; 1114 break; 1115 } 1116 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); 1117 } 1118 1119 case ISD::DECLARE: { 1120 SDValue Chain = Op.getOperand(0); 1121 SDValue N1 = Op.getOperand(1); 1122 SDValue N2 = Op.getOperand(2); 1123 FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(N1); 1124 // FIXME: handle VLAs. 1125 if (!FINode) { 1126 ReplaceUses(Op.getValue(0), Chain); 1127 return NULL; 1128 } 1129 if (N2.getOpcode() == ARMISD::PIC_ADD && isa<LoadSDNode>(N2.getOperand(0))) 1130 N2 = N2.getOperand(0); 1131 LoadSDNode *Ld = dyn_cast<LoadSDNode>(N2); 1132 if (!Ld) { 1133 ReplaceUses(Op.getValue(0), Chain); 1134 return NULL; 1135 } 1136 SDValue BasePtr = Ld->getBasePtr(); 1137 assert(BasePtr.getOpcode() == ARMISD::Wrapper && 1138 isa<ConstantPoolSDNode>(BasePtr.getOperand(0)) && 1139 "llvm.dbg.variable should be a constantpool node"); 1140 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(BasePtr.getOperand(0)); 1141 GlobalValue *GV = 0; 1142 if (CP->isMachineConstantPoolEntry()) { 1143 ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)CP->getMachineCPVal(); 1144 GV = ACPV->getGV(); 1145 } else 1146 GV = dyn_cast<GlobalValue>(CP->getConstVal()); 1147 if (!GV) { 1148 ReplaceUses(Op.getValue(0), Chain); 1149 return NULL; 1150 } 1151 1152 SDValue Tmp1 = CurDAG->getTargetFrameIndex(FINode->getIndex(), 1153 TLI.getPointerTy()); 1154 SDValue Tmp2 = CurDAG->getTargetGlobalAddress(GV, TLI.getPointerTy()); 1155 SDValue Ops[] = { Tmp1, Tmp2, Chain }; 1156 return CurDAG->getTargetNode(TargetInstrInfo::DECLARE, dl, 1157 MVT::Other, Ops, 3); 1158 } 1159 1160 case ISD::CONCAT_VECTORS: { 1161 MVT VT = Op.getValueType(); 1162 assert(VT.is128BitVector() && Op.getNumOperands() == 2 && 1163 "unexpected CONCAT_VECTORS"); 1164 SDValue N0 = Op.getOperand(0); 1165 SDValue N1 = Op.getOperand(1); 1166 SDNode *Result = 1167 CurDAG->getTargetNode(TargetInstrInfo::IMPLICIT_DEF, dl, VT); 1168 if (N0.getOpcode() != ISD::UNDEF) 1169 Result = CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG, dl, VT, 1170 SDValue(Result, 0), N0, 1171 CurDAG->getTargetConstant(arm_dsubreg_0, 1172 MVT::i32)); 1173 if (N1.getOpcode() != ISD::UNDEF) 1174 Result = CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG, dl, VT, 1175 SDValue(Result, 0), N1, 1176 CurDAG->getTargetConstant(arm_dsubreg_1, 1177 MVT::i32)); 1178 return Result; 1179 } 1180 1181 case ISD::VECTOR_SHUFFLE: { 1182 MVT VT = Op.getValueType(); 1183 1184 // Match 128-bit splat to VDUPLANEQ. (This could be done with a Pat in 1185 // ARMInstrNEON.td but it is awkward because the shuffle mask needs to be 1186 // transformed first into a lane number and then to both a subregister 1187 // index and an adjusted lane number.) If the source operand is a 1188 // SCALAR_TO_VECTOR, leave it so it will be matched later as a VDUP. 1189 ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N); 1190 if (VT.is128BitVector() && SVOp->isSplat() && 1191 Op.getOperand(0).getOpcode() != ISD::SCALAR_TO_VECTOR && 1192 Op.getOperand(1).getOpcode() == ISD::UNDEF) { 1193 unsigned LaneVal = SVOp->getSplatIndex(); 1194 1195 MVT HalfVT; 1196 unsigned Opc = 0; 1197 switch (VT.getVectorElementType().getSimpleVT()) { 1198 default: assert(false && "unhandled VDUP splat type"); 1199 case MVT::i8: Opc = ARM::VDUPLN8q; HalfVT = MVT::v8i8; break; 1200 case MVT::i16: Opc = ARM::VDUPLN16q; HalfVT = MVT::v4i16; break; 1201 case MVT::i32: Opc = ARM::VDUPLN32q; HalfVT = MVT::v2i32; break; 1202 case MVT::f32: Opc = ARM::VDUPLNfq; HalfVT = MVT::v2f32; break; 1203 } 1204 1205 // The source operand needs to be changed to a subreg of the original 1206 // 128-bit operand, and the lane number needs to be adjusted accordingly. 1207 unsigned NumElts = VT.getVectorNumElements() / 2; 1208 unsigned SRVal = (LaneVal < NumElts ? arm_dsubreg_0 : arm_dsubreg_1); 1209 SDValue SR = CurDAG->getTargetConstant(SRVal, MVT::i32); 1210 SDValue NewLane = CurDAG->getTargetConstant(LaneVal % NumElts, MVT::i32); 1211 SDNode *SubReg = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG, 1212 dl, HalfVT, N->getOperand(0), SR); 1213 return CurDAG->SelectNodeTo(N, Opc, VT, SDValue(SubReg, 0), NewLane); 1214 } 1215 1216 break; 1217 } 1218 } 1219 1220 return SelectCode(Op); 1221 } 1222 1223 bool ARMDAGToDAGISel:: 1224 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 1225 std::vector<SDValue> &OutOps) { 1226 assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); 1227 1228 SDValue Base, Offset, Opc; 1229 if (!SelectAddrMode2(Op, Op, Base, Offset, Opc)) 1230 return true; 1231 1232 OutOps.push_back(Base); 1233 OutOps.push_back(Offset); 1234 OutOps.push_back(Opc); 1235 return false; 1236 } 1237 1238 /// createARMISelDag - This pass converts a legalized DAG into a 1239 /// ARM-specific DAG, ready for instruction scheduling. 1240 /// 1241 FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM) { 1242 return new ARMDAGToDAGISel(TM); 1243 } 1244