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