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