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