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