ARMISelDAGToDAG.cpp revision d83360694a6d82772cf31a0be8a64570c2e5cb88
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 600 // Match frame index... 601 if (N.getOpcode() != ISD::ADD) { 602 if (N.getOpcode() == ISD::FrameIndex) { 603 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 604 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 605 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 606 return true; 607 } 608 return false; 609 } 610 611 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 612 int RHSC = (int)RHS->getZExtValue(); 613 if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits. 614 Base = N.getOperand(0); 615 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 616 return true; 617 } 618 } 619 620 return false; 621} 622 623bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue Op, SDValue N, 624 SDValue &Base, SDValue &OffImm) { 625 if ((N.getOpcode() == ISD::ADD) || (N.getOpcode() == ISD::SUB)) { 626 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 627 int RHSC = (int)RHS->getSExtValue(); 628 if (N.getOpcode() == ISD::SUB) 629 RHSC = -RHSC; 630 631 if ((RHSC >= -255) && (RHSC <= 0)) { // 8 bits (always negative) 632 Base = N.getOperand(0); 633 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 634 return true; 635 } 636 } else if (N.getOpcode() == ISD::SUB) { 637 Base = N; 638 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 639 return true; 640 } 641 } 642 643 return false; 644} 645 646bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDValue Op, SDValue N, 647 SDValue &OffImm){ 648 unsigned Opcode = Op.getOpcode(); 649 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 650 ? cast<LoadSDNode>(Op)->getAddressingMode() 651 : cast<StoreSDNode>(Op)->getAddressingMode(); 652 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N)) { 653 int RHSC = (int)RHS->getZExtValue(); 654 if (RHSC >= 0 && RHSC < 0x100) { // 8 bits. 655 OffImm = ((AM == ISD::PRE_INC) || (AM == ISD::POST_INC)) 656 ? CurDAG->getTargetConstant(RHSC, MVT::i32) 657 : CurDAG->getTargetConstant(-RHSC, MVT::i32); 658 return true; 659 } 660 } 661 662 return false; 663} 664 665bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDValue Op, SDValue N, 666 SDValue &Base, SDValue &OffImm) { 667 if (N.getOpcode() == ISD::ADD) { 668 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 669 int RHSC = (int)RHS->getZExtValue(); 670 if (((RHSC & 0x3) == 0) && 671 ((RHSC >= 0 && RHSC < 0x400) || (RHSC < 0 && RHSC > -0x400))) { // 8 bits. 672 Base = N.getOperand(0); 673 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 674 return true; 675 } 676 } 677 } else if (N.getOpcode() == ISD::SUB) { 678 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 679 int RHSC = (int)RHS->getZExtValue(); 680 if (((RHSC & 0x3) == 0) && (RHSC >= 0 && RHSC < 0x400)) { // 8 bits. 681 Base = N.getOperand(0); 682 OffImm = CurDAG->getTargetConstant(-RHSC, MVT::i32); 683 return true; 684 } 685 } 686 } 687 688 return false; 689} 690 691bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue Op, SDValue N, 692 SDValue &Base, 693 SDValue &OffReg, SDValue &ShImm) { 694 // Base only. 695 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 696 Base = N; 697 if (N.getOpcode() == ISD::FrameIndex) { 698 return false; // we want to select t2LDRri12 instead 699 } else if (N.getOpcode() == ARMISD::Wrapper) { 700 Base = N.getOperand(0); 701 if (Base.getOpcode() == ISD::TargetConstantPool) 702 return false; // We want to select t2LDRpci instead. 703 } 704 OffReg = CurDAG->getRegister(0, MVT::i32); 705 ShImm = CurDAG->getTargetConstant(0, MVT::i32); 706 return true; 707 } 708 709 // Thumb2 does not support (R - R) or (R - (R << [1,2,3])). 710 if (N.getOpcode() != ISD::ADD) 711 return false; 712 713 // Look for (R + R) or (R + (R << [1,2,3])). 714 unsigned ShAmt = 0; 715 Base = N.getOperand(0); 716 OffReg = N.getOperand(1); 717 718 // Swap if it is ((R << c) + R). 719 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg); 720 if (ShOpcVal != ARM_AM::lsl) { 721 ShOpcVal = ARM_AM::getShiftOpcForNode(Base); 722 if (ShOpcVal == ARM_AM::lsl) 723 std::swap(Base, OffReg); 724 } 725 726 if (ShOpcVal == ARM_AM::lsl) { 727 // Check to see if the RHS of the shift is a constant, if not, we can't fold 728 // it. 729 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(OffReg.getOperand(1))) { 730 ShAmt = Sh->getZExtValue(); 731 if (ShAmt >= 4) { 732 ShAmt = 0; 733 ShOpcVal = ARM_AM::no_shift; 734 } else 735 OffReg = OffReg.getOperand(0); 736 } else { 737 ShOpcVal = ARM_AM::no_shift; 738 } 739 } else if (SelectT2AddrModeImm12(Op, N, Base, ShImm) || 740 SelectT2AddrModeImm8 (Op, N, Base, ShImm)) { 741 // Don't match if it's possible to match to one of the r +/- imm cases. 742 return false; 743 } 744 745 ShImm = CurDAG->getTargetConstant(ShAmt, MVT::i32); 746 747 return true; 748} 749 750//===--------------------------------------------------------------------===// 751 752/// getAL - Returns a ARMCC::AL immediate node. 753static inline SDValue getAL(SelectionDAG *CurDAG) { 754 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32); 755} 756 757SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) { 758 LoadSDNode *LD = cast<LoadSDNode>(Op); 759 ISD::MemIndexedMode AM = LD->getAddressingMode(); 760 if (AM == ISD::UNINDEXED) 761 return NULL; 762 763 MVT LoadedVT = LD->getMemoryVT(); 764 SDValue Offset, AMOpc; 765 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 766 unsigned Opcode = 0; 767 bool Match = false; 768 if (LoadedVT == MVT::i32 && 769 SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { 770 Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST; 771 Match = true; 772 } else if (LoadedVT == MVT::i16 && 773 SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { 774 Match = true; 775 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) 776 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) 777 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); 778 } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) { 779 if (LD->getExtensionType() == ISD::SEXTLOAD) { 780 if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { 781 Match = true; 782 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; 783 } 784 } else { 785 if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { 786 Match = true; 787 Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST; 788 } 789 } 790 } 791 792 if (Match) { 793 SDValue Chain = LD->getChain(); 794 SDValue Base = LD->getBasePtr(); 795 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), 796 CurDAG->getRegister(0, MVT::i32), Chain }; 797 return CurDAG->getTargetNode(Opcode, Op.getDebugLoc(), MVT::i32, MVT::i32, 798 MVT::Other, Ops, 6); 799 } 800 801 return NULL; 802} 803 804SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDValue Op) { 805 LoadSDNode *LD = cast<LoadSDNode>(Op); 806 ISD::MemIndexedMode AM = LD->getAddressingMode(); 807 if (AM == ISD::UNINDEXED) 808 return NULL; 809 810 MVT LoadedVT = LD->getMemoryVT(); 811 bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD; 812 SDValue Offset; 813 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 814 unsigned Opcode = 0; 815 bool Match = false; 816 if (SelectT2AddrModeImm8Offset(Op, LD->getOffset(), Offset)) { 817 switch (LoadedVT.getSimpleVT()) { 818 case MVT::i32: 819 Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST; 820 break; 821 case MVT::i16: 822 if (isSExtLd) 823 Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST; 824 else 825 Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST; 826 break; 827 case MVT::i8: 828 case MVT::i1: 829 if (isSExtLd) 830 Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST; 831 else 832 Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST; 833 break; 834 default: 835 return NULL; 836 } 837 Match = true; 838 } 839 840 if (Match) { 841 SDValue Chain = LD->getChain(); 842 SDValue Base = LD->getBasePtr(); 843 SDValue Ops[]= { Base, Offset, getAL(CurDAG), 844 CurDAG->getRegister(0, MVT::i32), Chain }; 845 return CurDAG->getTargetNode(Opcode, Op.getDebugLoc(), MVT::i32, MVT::i32, 846 MVT::Other, Ops, 5); 847 } 848 849 return NULL; 850} 851 852 853SDNode *ARMDAGToDAGISel::Select(SDValue Op) { 854 SDNode *N = Op.getNode(); 855 DebugLoc dl = N->getDebugLoc(); 856 857 if (N->isMachineOpcode()) 858 return NULL; // Already selected. 859 860 switch (N->getOpcode()) { 861 default: break; 862 case ISD::Constant: { 863 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 864 bool UseCP = true; 865 if (Subtarget->isThumb()) { 866 if (Subtarget->hasThumb2()) 867 // Thumb2 has the MOVT instruction, so all immediates can 868 // be done with MOV + MOVT, at worst. 869 UseCP = 0; 870 else 871 UseCP = (Val > 255 && // MOV 872 ~Val > 255 && // MOV + MVN 873 !ARM_AM::isThumbImmShiftedVal(Val)); // MOV + LSL 874 } else 875 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV 876 ARM_AM::getSOImmVal(~Val) == -1 && // MVN 877 !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs. 878 if (UseCP) { 879 SDValue CPIdx = 880 CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val), 881 TLI.getPointerTy()); 882 883 SDNode *ResNode; 884 if (Subtarget->isThumb1Only()) { 885 SDValue Pred = CurDAG->getTargetConstant(0xEULL, MVT::i32); 886 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); 887 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() }; 888 ResNode = CurDAG->getTargetNode(ARM::tLDRcp, dl, MVT::i32, MVT::Other, 889 Ops, 4); 890 } else { 891 SDValue Ops[] = { 892 CPIdx, 893 CurDAG->getRegister(0, MVT::i32), 894 CurDAG->getTargetConstant(0, MVT::i32), 895 getAL(CurDAG), 896 CurDAG->getRegister(0, MVT::i32), 897 CurDAG->getEntryNode() 898 }; 899 ResNode=CurDAG->getTargetNode(ARM::LDRcp, dl, MVT::i32, MVT::Other, 900 Ops, 6); 901 } 902 ReplaceUses(Op, SDValue(ResNode, 0)); 903 return NULL; 904 } 905 906 // Other cases are autogenerated. 907 break; 908 } 909 case ISD::FrameIndex: { 910 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. 911 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 912 SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 913 if (Subtarget->isThumb1Only()) { 914 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI, 915 CurDAG->getTargetConstant(0, MVT::i32)); 916 } else { 917 unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ? 918 ARM::t2ADDri : ARM::ADDri); 919 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), 920 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 921 CurDAG->getRegister(0, MVT::i32) }; 922 return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5); 923 } 924 } 925 case ISD::ADD: { 926 if (!Subtarget->isThumb1Only()) 927 break; 928 // Select add sp, c to tADDhirr. 929 SDValue N0 = Op.getOperand(0); 930 SDValue N1 = Op.getOperand(1); 931 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(Op.getOperand(0)); 932 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(Op.getOperand(1)); 933 if (LHSR && LHSR->getReg() == ARM::SP) { 934 std::swap(N0, N1); 935 std::swap(LHSR, RHSR); 936 } 937 if (RHSR && RHSR->getReg() == ARM::SP) { 938 SDValue Val = SDValue(CurDAG->getTargetNode(ARM::tMOVtgpr2gpr, dl, 939 Op.getValueType(), N0, N0),0); 940 return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType(), Val, N1); 941 } 942 break; 943 } 944 case ISD::MUL: 945 if (Subtarget->isThumb1Only()) 946 break; 947 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { 948 unsigned RHSV = C->getZExtValue(); 949 if (!RHSV) break; 950 if (isPowerOf2_32(RHSV-1)) { // 2^n+1? 951 unsigned ShImm = Log2_32(RHSV-1); 952 if (ShImm >= 32) 953 break; 954 SDValue V = Op.getOperand(0); 955 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 956 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); 957 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 958 if (Subtarget->isThumb()) { 959 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 960 return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops, 6); 961 } else { 962 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 963 return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7); 964 } 965 } 966 if (isPowerOf2_32(RHSV+1)) { // 2^n-1? 967 unsigned ShImm = Log2_32(RHSV+1); 968 if (ShImm >= 32) 969 break; 970 SDValue V = Op.getOperand(0); 971 ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm); 972 SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32); 973 SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); 974 if (Subtarget->isThumb()) { 975 SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0 }; 976 return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops, 5); 977 } else { 978 SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; 979 return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7); 980 } 981 } 982 } 983 break; 984 case ARMISD::FMRRD: 985 return CurDAG->getTargetNode(ARM::FMRRD, dl, MVT::i32, MVT::i32, 986 Op.getOperand(0), getAL(CurDAG), 987 CurDAG->getRegister(0, MVT::i32)); 988 case ISD::UMUL_LOHI: { 989 if (Subtarget->isThumb1Only()) 990 break; 991 if (Subtarget->isThumb()) { 992 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 993 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 994 CurDAG->getRegister(0, MVT::i32) }; 995 return CurDAG->getTargetNode(ARM::t2UMULL, dl, MVT::i32, MVT::i32, Ops,4); 996 } else { 997 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 998 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 999 CurDAG->getRegister(0, MVT::i32) }; 1000 return CurDAG->getTargetNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5); 1001 } 1002 } 1003 case ISD::SMUL_LOHI: { 1004 if (Subtarget->isThumb1Only()) 1005 break; 1006 if (Subtarget->isThumb()) { 1007 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 1008 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; 1009 return CurDAG->getTargetNode(ARM::t2SMULL, dl, MVT::i32, MVT::i32, Ops,4); 1010 } else { 1011 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 1012 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 1013 CurDAG->getRegister(0, MVT::i32) }; 1014 return CurDAG->getTargetNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5); 1015 } 1016 } 1017 case ISD::LOAD: { 1018 SDNode *ResNode = 0; 1019 if (Subtarget->isThumb() && Subtarget->hasThumb2()) 1020 ResNode = SelectT2IndexedLoad(Op); 1021 else 1022 ResNode = SelectARMIndexedLoad(Op); 1023 if (ResNode) 1024 return ResNode; 1025 // Other cases are autogenerated. 1026 break; 1027 } 1028 case ARMISD::BRCOND: { 1029 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1030 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc) 1031 // Pattern complexity = 6 cost = 1 size = 0 1032 1033 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1034 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc) 1035 // Pattern complexity = 6 cost = 1 size = 0 1036 1037 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 1038 // Emits: (t2Bcc:void (bb:Other):$dst, (imm:i32):$cc) 1039 // Pattern complexity = 6 cost = 1 size = 0 1040 1041 unsigned Opc = Subtarget->isThumb() ? 1042 ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; 1043 SDValue Chain = Op.getOperand(0); 1044 SDValue N1 = Op.getOperand(1); 1045 SDValue N2 = Op.getOperand(2); 1046 SDValue N3 = Op.getOperand(3); 1047 SDValue InFlag = Op.getOperand(4); 1048 assert(N1.getOpcode() == ISD::BasicBlock); 1049 assert(N2.getOpcode() == ISD::Constant); 1050 assert(N3.getOpcode() == ISD::Register); 1051 1052 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1053 cast<ConstantSDNode>(N2)->getZExtValue()), 1054 MVT::i32); 1055 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; 1056 SDNode *ResNode = CurDAG->getTargetNode(Opc, dl, MVT::Other, 1057 MVT::Flag, Ops, 5); 1058 Chain = SDValue(ResNode, 0); 1059 if (Op.getNode()->getNumValues() == 2) { 1060 InFlag = SDValue(ResNode, 1); 1061 ReplaceUses(SDValue(Op.getNode(), 1), InFlag); 1062 } 1063 ReplaceUses(SDValue(Op.getNode(), 0), SDValue(Chain.getNode(), Chain.getResNo())); 1064 return NULL; 1065 } 1066 case ARMISD::CMOV: { 1067 MVT VT = Op.getValueType(); 1068 SDValue N0 = Op.getOperand(0); 1069 SDValue N1 = Op.getOperand(1); 1070 SDValue N2 = Op.getOperand(2); 1071 SDValue N3 = Op.getOperand(3); 1072 SDValue InFlag = Op.getOperand(4); 1073 assert(N2.getOpcode() == ISD::Constant); 1074 assert(N3.getOpcode() == ISD::Register); 1075 1076 if (!Subtarget->isThumb1Only() && VT == MVT::i32) { 1077 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1078 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 1079 // Pattern complexity = 18 cost = 1 size = 0 1080 SDValue CPTmp0; 1081 SDValue CPTmp1; 1082 SDValue CPTmp2; 1083 if (Subtarget->isThumb()) { 1084 if (SelectT2ShifterOperandReg(Op, N1, CPTmp0, CPTmp1)) { 1085 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1086 cast<ConstantSDNode>(N2)->getZExtValue()), 1087 MVT::i32); 1088 SDValue Ops[] = { N0, CPTmp0, CPTmp1, Tmp2, N3, InFlag }; 1089 return CurDAG->SelectNodeTo(Op.getNode(), 1090 ARM::t2MOVCCs, MVT::i32,Ops, 6); 1091 } 1092 } else { 1093 if (SelectShifterOperandReg(Op, N1, CPTmp0, CPTmp1, CPTmp2)) { 1094 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1095 cast<ConstantSDNode>(N2)->getZExtValue()), 1096 MVT::i32); 1097 SDValue Ops[] = { N0, CPTmp0, CPTmp1, CPTmp2, Tmp2, N3, InFlag }; 1098 return CurDAG->SelectNodeTo(Op.getNode(), 1099 ARM::MOVCCs, MVT::i32, Ops, 7); 1100 } 1101 } 1102 1103 // Pattern: (ARMcmov:i32 GPR:i32:$false, 1104 // (imm:i32)<<P:Predicate_so_imm>>:$true, 1105 // (imm:i32):$cc) 1106 // Emits: (MOVCCi:i32 GPR:i32:$false, 1107 // (so_imm:i32 (imm:i32):$true), (imm:i32):$cc) 1108 // Pattern complexity = 10 cost = 1 size = 0 1109 if (N3.getOpcode() == ISD::Constant) { 1110 if (Subtarget->isThumb()) { 1111 if (Predicate_t2_so_imm(N3.getNode())) { 1112 SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned) 1113 cast<ConstantSDNode>(N1)->getZExtValue()), 1114 MVT::i32); 1115 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1116 cast<ConstantSDNode>(N2)->getZExtValue()), 1117 MVT::i32); 1118 SDValue Ops[] = { N0, Tmp1, Tmp2, N3, InFlag }; 1119 return CurDAG->SelectNodeTo(Op.getNode(), 1120 ARM::t2MOVCCi, MVT::i32, Ops, 5); 1121 } 1122 } else { 1123 if (Predicate_so_imm(N3.getNode())) { 1124 SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned) 1125 cast<ConstantSDNode>(N1)->getZExtValue()), 1126 MVT::i32); 1127 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1128 cast<ConstantSDNode>(N2)->getZExtValue()), 1129 MVT::i32); 1130 SDValue Ops[] = { N0, Tmp1, Tmp2, N3, InFlag }; 1131 return CurDAG->SelectNodeTo(Op.getNode(), 1132 ARM::MOVCCi, MVT::i32, Ops, 5); 1133 } 1134 } 1135 } 1136 } 1137 1138 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1139 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1140 // Pattern complexity = 6 cost = 1 size = 0 1141 // 1142 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1143 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 1144 // Pattern complexity = 6 cost = 11 size = 0 1145 // 1146 // Also FCPYScc and FCPYDcc. 1147 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1148 cast<ConstantSDNode>(N2)->getZExtValue()), 1149 MVT::i32); 1150 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 1151 unsigned Opc = 0; 1152 switch (VT.getSimpleVT()) { 1153 default: assert(false && "Illegal conditional move type!"); 1154 break; 1155 case MVT::i32: 1156 Opc = Subtarget->isThumb() 1157 ? (Subtarget->hasThumb2() ? ARM::t2MOVCCr : ARM::tMOVCCr) 1158 : ARM::MOVCCr; 1159 break; 1160 case MVT::f32: 1161 Opc = ARM::FCPYScc; 1162 break; 1163 case MVT::f64: 1164 Opc = ARM::FCPYDcc; 1165 break; 1166 } 1167 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); 1168 } 1169 case ARMISD::CNEG: { 1170 MVT VT = Op.getValueType(); 1171 SDValue N0 = Op.getOperand(0); 1172 SDValue N1 = Op.getOperand(1); 1173 SDValue N2 = Op.getOperand(2); 1174 SDValue N3 = Op.getOperand(3); 1175 SDValue InFlag = Op.getOperand(4); 1176 assert(N2.getOpcode() == ISD::Constant); 1177 assert(N3.getOpcode() == ISD::Register); 1178 1179 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 1180 cast<ConstantSDNode>(N2)->getZExtValue()), 1181 MVT::i32); 1182 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 1183 unsigned Opc = 0; 1184 switch (VT.getSimpleVT()) { 1185 default: assert(false && "Illegal conditional move type!"); 1186 break; 1187 case MVT::f32: 1188 Opc = ARM::FNEGScc; 1189 break; 1190 case MVT::f64: 1191 Opc = ARM::FNEGDcc; 1192 break; 1193 } 1194 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); 1195 } 1196 1197 case ISD::DECLARE: { 1198 SDValue Chain = Op.getOperand(0); 1199 SDValue N1 = Op.getOperand(1); 1200 SDValue N2 = Op.getOperand(2); 1201 FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(N1); 1202 // FIXME: handle VLAs. 1203 if (!FINode) { 1204 ReplaceUses(Op.getValue(0), Chain); 1205 return NULL; 1206 } 1207 if (N2.getOpcode() == ARMISD::PIC_ADD && isa<LoadSDNode>(N2.getOperand(0))) 1208 N2 = N2.getOperand(0); 1209 LoadSDNode *Ld = dyn_cast<LoadSDNode>(N2); 1210 if (!Ld) { 1211 ReplaceUses(Op.getValue(0), Chain); 1212 return NULL; 1213 } 1214 SDValue BasePtr = Ld->getBasePtr(); 1215 assert(BasePtr.getOpcode() == ARMISD::Wrapper && 1216 isa<ConstantPoolSDNode>(BasePtr.getOperand(0)) && 1217 "llvm.dbg.variable should be a constantpool node"); 1218 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(BasePtr.getOperand(0)); 1219 GlobalValue *GV = 0; 1220 if (CP->isMachineConstantPoolEntry()) { 1221 ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)CP->getMachineCPVal(); 1222 GV = ACPV->getGV(); 1223 } else 1224 GV = dyn_cast<GlobalValue>(CP->getConstVal()); 1225 if (!GV) { 1226 ReplaceUses(Op.getValue(0), Chain); 1227 return NULL; 1228 } 1229 1230 SDValue Tmp1 = CurDAG->getTargetFrameIndex(FINode->getIndex(), 1231 TLI.getPointerTy()); 1232 SDValue Tmp2 = CurDAG->getTargetGlobalAddress(GV, TLI.getPointerTy()); 1233 SDValue Ops[] = { Tmp1, Tmp2, Chain }; 1234 return CurDAG->getTargetNode(TargetInstrInfo::DECLARE, dl, 1235 MVT::Other, Ops, 3); 1236 } 1237 1238 case ISD::CONCAT_VECTORS: { 1239 MVT VT = Op.getValueType(); 1240 assert(VT.is128BitVector() && Op.getNumOperands() == 2 && 1241 "unexpected CONCAT_VECTORS"); 1242 SDValue N0 = Op.getOperand(0); 1243 SDValue N1 = Op.getOperand(1); 1244 SDNode *Result = 1245 CurDAG->getTargetNode(TargetInstrInfo::IMPLICIT_DEF, dl, VT); 1246 if (N0.getOpcode() != ISD::UNDEF) 1247 Result = CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG, dl, VT, 1248 SDValue(Result, 0), N0, 1249 CurDAG->getTargetConstant(arm_dsubreg_0, 1250 MVT::i32)); 1251 if (N1.getOpcode() != ISD::UNDEF) 1252 Result = CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG, dl, VT, 1253 SDValue(Result, 0), N1, 1254 CurDAG->getTargetConstant(arm_dsubreg_1, 1255 MVT::i32)); 1256 return Result; 1257 } 1258 1259 case ISD::VECTOR_SHUFFLE: { 1260 MVT VT = Op.getValueType(); 1261 1262 // Match 128-bit splat to VDUPLANEQ. (This could be done with a Pat in 1263 // ARMInstrNEON.td but it is awkward because the shuffle mask needs to be 1264 // transformed first into a lane number and then to both a subregister 1265 // index and an adjusted lane number.) If the source operand is a 1266 // SCALAR_TO_VECTOR, leave it so it will be matched later as a VDUP. 1267 ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N); 1268 if (VT.is128BitVector() && SVOp->isSplat() && 1269 Op.getOperand(0).getOpcode() != ISD::SCALAR_TO_VECTOR && 1270 Op.getOperand(1).getOpcode() == ISD::UNDEF) { 1271 unsigned LaneVal = SVOp->getSplatIndex(); 1272 1273 MVT HalfVT; 1274 unsigned Opc = 0; 1275 switch (VT.getVectorElementType().getSimpleVT()) { 1276 default: assert(false && "unhandled VDUP splat type"); 1277 case MVT::i8: Opc = ARM::VDUPLN8q; HalfVT = MVT::v8i8; break; 1278 case MVT::i16: Opc = ARM::VDUPLN16q; HalfVT = MVT::v4i16; break; 1279 case MVT::i32: Opc = ARM::VDUPLN32q; HalfVT = MVT::v2i32; break; 1280 case MVT::f32: Opc = ARM::VDUPLNfq; HalfVT = MVT::v2f32; break; 1281 } 1282 1283 // The source operand needs to be changed to a subreg of the original 1284 // 128-bit operand, and the lane number needs to be adjusted accordingly. 1285 unsigned NumElts = VT.getVectorNumElements() / 2; 1286 unsigned SRVal = (LaneVal < NumElts ? arm_dsubreg_0 : arm_dsubreg_1); 1287 SDValue SR = CurDAG->getTargetConstant(SRVal, MVT::i32); 1288 SDValue NewLane = CurDAG->getTargetConstant(LaneVal % NumElts, MVT::i32); 1289 SDNode *SubReg = CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG, 1290 dl, HalfVT, N->getOperand(0), SR); 1291 return CurDAG->SelectNodeTo(N, Opc, VT, SDValue(SubReg, 0), NewLane); 1292 } 1293 1294 break; 1295 } 1296 } 1297 1298 return SelectCode(Op); 1299} 1300 1301bool ARMDAGToDAGISel:: 1302SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 1303 std::vector<SDValue> &OutOps) { 1304 assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); 1305 1306 SDValue Base, Offset, Opc; 1307 if (!SelectAddrMode2(Op, Op, Base, Offset, Opc)) 1308 return true; 1309 1310 OutOps.push_back(Base); 1311 OutOps.push_back(Offset); 1312 OutOps.push_back(Opc); 1313 return false; 1314} 1315 1316/// createARMISelDag - This pass converts a legalized DAG into a 1317/// ARM-specific DAG, ready for instruction scheduling. 1318/// 1319FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM) { 1320 return new ARMDAGToDAGISel(TM); 1321} 1322