ARMISelDAGToDAG.cpp revision 8ad4c00c00233acb8a3395098e2b575cc34de46b
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 "ARMISelLowering.h" 16#include "ARMTargetMachine.h" 17#include "ARMAddressingModes.h" 18#include "llvm/CallingConv.h" 19#include "llvm/Constants.h" 20#include "llvm/DerivedTypes.h" 21#include "llvm/Function.h" 22#include "llvm/Intrinsics.h" 23#include "llvm/CodeGen/MachineFrameInfo.h" 24#include "llvm/CodeGen/MachineFunction.h" 25#include "llvm/CodeGen/MachineInstrBuilder.h" 26#include "llvm/CodeGen/SelectionDAG.h" 27#include "llvm/CodeGen/SelectionDAGISel.h" 28#include "llvm/Target/TargetLowering.h" 29#include "llvm/Target/TargetOptions.h" 30#include "llvm/Support/Compiler.h" 31#include "llvm/Support/Debug.h" 32using namespace llvm; 33 34//===--------------------------------------------------------------------===// 35/// ARMDAGToDAGISel - ARM specific code to select ARM machine 36/// instructions for SelectionDAG operations. 37/// 38namespace { 39class ARMDAGToDAGISel : public SelectionDAGISel { 40 ARMTargetMachine &TM; 41 42 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 43 /// make the right decision when generating code for different targets. 44 const ARMSubtarget *Subtarget; 45 46public: 47 explicit ARMDAGToDAGISel(ARMTargetMachine &tm) 48 : SelectionDAGISel(*tm.getTargetLowering()), TM(tm), 49 Subtarget(&TM.getSubtarget<ARMSubtarget>()) { 50 } 51 52 virtual const char *getPassName() const { 53 return "ARM Instruction Selection"; 54 } 55 56 SDNode *Select(SDValue Op); 57 virtual void InstructionSelect(); 58 bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base, 59 SDValue &Offset, SDValue &Opc); 60 bool SelectAddrMode2Offset(SDValue Op, SDValue N, 61 SDValue &Offset, SDValue &Opc); 62 bool SelectAddrMode3(SDValue Op, SDValue N, SDValue &Base, 63 SDValue &Offset, SDValue &Opc); 64 bool SelectAddrMode3Offset(SDValue Op, SDValue N, 65 SDValue &Offset, SDValue &Opc); 66 bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base, 67 SDValue &Offset); 68 69 bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset, 70 SDValue &Label); 71 72 bool SelectThumbAddrModeRR(SDValue Op, SDValue N, SDValue &Base, 73 SDValue &Offset); 74 bool SelectThumbAddrModeRI5(SDValue Op, SDValue N, unsigned Scale, 75 SDValue &Base, SDValue &OffImm, 76 SDValue &Offset); 77 bool SelectThumbAddrModeS1(SDValue Op, SDValue N, SDValue &Base, 78 SDValue &OffImm, SDValue &Offset); 79 bool SelectThumbAddrModeS2(SDValue Op, SDValue N, SDValue &Base, 80 SDValue &OffImm, SDValue &Offset); 81 bool SelectThumbAddrModeS4(SDValue Op, SDValue N, SDValue &Base, 82 SDValue &OffImm, SDValue &Offset); 83 bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base, 84 SDValue &OffImm); 85 86 bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A, 87 SDValue &B, SDValue &C); 88 89 // Include the pieces autogenerated from the target description. 90#include "ARMGenDAGISel.inc" 91}; 92} 93 94void ARMDAGToDAGISel::InstructionSelect() { 95 DEBUG(BB->dump()); 96 97 SelectRoot(*CurDAG); 98 CurDAG->RemoveDeadNodes(); 99} 100 101bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N, 102 SDValue &Base, SDValue &Offset, 103 SDValue &Opc) { 104 if (N.getOpcode() == ISD::MUL) { 105 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 106 // X * [3,5,9] -> X + X * [2,4,8] etc. 107 int RHSC = (int)RHS->getZExtValue(); 108 if (RHSC & 1) { 109 RHSC = RHSC & ~1; 110 ARM_AM::AddrOpc AddSub = ARM_AM::add; 111 if (RHSC < 0) { 112 AddSub = ARM_AM::sub; 113 RHSC = - RHSC; 114 } 115 if (isPowerOf2_32(RHSC)) { 116 unsigned ShAmt = Log2_32(RHSC); 117 Base = Offset = N.getOperand(0); 118 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, 119 ARM_AM::lsl), 120 MVT::i32); 121 return true; 122 } 123 } 124 } 125 } 126 127 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) { 128 Base = N; 129 if (N.getOpcode() == ISD::FrameIndex) { 130 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 131 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 132 } else if (N.getOpcode() == ARMISD::Wrapper) { 133 Base = N.getOperand(0); 134 } 135 Offset = CurDAG->getRegister(0, MVT::i32); 136 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, 137 ARM_AM::no_shift), 138 MVT::i32); 139 return true; 140 } 141 142 // Match simple R +/- imm12 operands. 143 if (N.getOpcode() == ISD::ADD) 144 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 145 int RHSC = (int)RHS->getZExtValue(); 146 if ((RHSC >= 0 && RHSC < 0x1000) || 147 (RHSC < 0 && RHSC > -0x1000)) { // 12 bits. 148 Base = N.getOperand(0); 149 if (Base.getOpcode() == ISD::FrameIndex) { 150 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 151 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 152 } 153 Offset = CurDAG->getRegister(0, MVT::i32); 154 155 ARM_AM::AddrOpc AddSub = ARM_AM::add; 156 if (RHSC < 0) { 157 AddSub = ARM_AM::sub; 158 RHSC = - RHSC; 159 } 160 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC, 161 ARM_AM::no_shift), 162 MVT::i32); 163 return true; 164 } 165 } 166 167 // Otherwise this is R +/- [possibly shifted] R 168 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub; 169 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1)); 170 unsigned ShAmt = 0; 171 172 Base = N.getOperand(0); 173 Offset = N.getOperand(1); 174 175 if (ShOpcVal != ARM_AM::no_shift) { 176 // Check to see if the RHS of the shift is a constant, if not, we can't fold 177 // it. 178 if (ConstantSDNode *Sh = 179 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) { 180 ShAmt = Sh->getZExtValue(); 181 Offset = N.getOperand(1).getOperand(0); 182 } else { 183 ShOpcVal = ARM_AM::no_shift; 184 } 185 } 186 187 // Try matching (R shl C) + (R). 188 if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) { 189 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0)); 190 if (ShOpcVal != ARM_AM::no_shift) { 191 // Check to see if the RHS of the shift is a constant, if not, we can't 192 // fold it. 193 if (ConstantSDNode *Sh = 194 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) { 195 ShAmt = Sh->getZExtValue(); 196 Offset = N.getOperand(0).getOperand(0); 197 Base = N.getOperand(1); 198 } else { 199 ShOpcVal = ARM_AM::no_shift; 200 } 201 } 202 } 203 204 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 205 MVT::i32); 206 return true; 207} 208 209bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDValue Op, SDValue N, 210 SDValue &Offset, SDValue &Opc) { 211 unsigned Opcode = Op.getOpcode(); 212 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 213 ? cast<LoadSDNode>(Op)->getAddressingMode() 214 : cast<StoreSDNode>(Op)->getAddressingMode(); 215 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 216 ? ARM_AM::add : ARM_AM::sub; 217 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 218 int Val = (int)C->getZExtValue(); 219 if (Val >= 0 && Val < 0x1000) { // 12 bits. 220 Offset = CurDAG->getRegister(0, MVT::i32); 221 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, 222 ARM_AM::no_shift), 223 MVT::i32); 224 return true; 225 } 226 } 227 228 Offset = N; 229 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 230 unsigned ShAmt = 0; 231 if (ShOpcVal != ARM_AM::no_shift) { 232 // Check to see if the RHS of the shift is a constant, if not, we can't fold 233 // it. 234 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 235 ShAmt = Sh->getZExtValue(); 236 Offset = N.getOperand(0); 237 } else { 238 ShOpcVal = ARM_AM::no_shift; 239 } 240 } 241 242 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), 243 MVT::i32); 244 return true; 245} 246 247 248bool ARMDAGToDAGISel::SelectAddrMode3(SDValue Op, SDValue N, 249 SDValue &Base, SDValue &Offset, 250 SDValue &Opc) { 251 if (N.getOpcode() == ISD::SUB) { 252 // X - C is canonicalize to X + -C, no need to handle it here. 253 Base = N.getOperand(0); 254 Offset = N.getOperand(1); 255 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32); 256 return true; 257 } 258 259 if (N.getOpcode() != ISD::ADD) { 260 Base = N; 261 if (N.getOpcode() == ISD::FrameIndex) { 262 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 263 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 264 } 265 Offset = CurDAG->getRegister(0, MVT::i32); 266 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32); 267 return true; 268 } 269 270 // If the RHS is +/- imm8, fold into addr mode. 271 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 272 int RHSC = (int)RHS->getZExtValue(); 273 if ((RHSC >= 0 && RHSC < 256) || 274 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 275 Base = N.getOperand(0); 276 if (Base.getOpcode() == ISD::FrameIndex) { 277 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 278 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 279 } 280 Offset = CurDAG->getRegister(0, MVT::i32); 281 282 ARM_AM::AddrOpc AddSub = ARM_AM::add; 283 if (RHSC < 0) { 284 AddSub = ARM_AM::sub; 285 RHSC = - RHSC; 286 } 287 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32); 288 return true; 289 } 290 } 291 292 Base = N.getOperand(0); 293 Offset = N.getOperand(1); 294 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32); 295 return true; 296} 297 298bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N, 299 SDValue &Offset, SDValue &Opc) { 300 unsigned Opcode = Op.getOpcode(); 301 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) 302 ? cast<LoadSDNode>(Op)->getAddressingMode() 303 : cast<StoreSDNode>(Op)->getAddressingMode(); 304 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) 305 ? ARM_AM::add : ARM_AM::sub; 306 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 307 int Val = (int)C->getZExtValue(); 308 if (Val >= 0 && Val < 256) { 309 Offset = CurDAG->getRegister(0, MVT::i32); 310 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32); 311 return true; 312 } 313 } 314 315 Offset = N; 316 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32); 317 return true; 318} 319 320 321bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N, 322 SDValue &Base, SDValue &Offset) { 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 } else if (N.getOpcode() == ARMISD::Wrapper) { 329 Base = N.getOperand(0); 330 } 331 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 332 MVT::i32); 333 return true; 334 } 335 336 // If the RHS is +/- imm8, fold into addr mode. 337 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 338 int RHSC = (int)RHS->getZExtValue(); 339 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied by 4. 340 RHSC >>= 2; 341 if ((RHSC >= 0 && RHSC < 256) || 342 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed. 343 Base = N.getOperand(0); 344 if (Base.getOpcode() == ISD::FrameIndex) { 345 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 346 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 347 } 348 349 ARM_AM::AddrOpc AddSub = ARM_AM::add; 350 if (RHSC < 0) { 351 AddSub = ARM_AM::sub; 352 RHSC = - RHSC; 353 } 354 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC), 355 MVT::i32); 356 return true; 357 } 358 } 359 } 360 361 Base = N; 362 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), 363 MVT::i32); 364 return true; 365} 366 367bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N, 368 SDValue &Offset, SDValue &Label) { 369 if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { 370 Offset = N.getOperand(0); 371 SDValue N1 = N.getOperand(1); 372 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(), 373 MVT::i32); 374 return true; 375 } 376 return false; 377} 378 379bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op, SDValue N, 380 SDValue &Base, SDValue &Offset){ 381 if (N.getOpcode() != ISD::ADD) { 382 Base = N; 383 // We must materialize a zero in a reg! Returning an constant here won't 384 // work since its node is -1 so it won't get added to the selection queue. 385 // Explicitly issue a tMOVri8 node! 386 Offset = SDValue(CurDAG->getTargetNode(ARM::tMOVi8, MVT::i32, 387 CurDAG->getTargetConstant(0, MVT::i32)), 0); 388 return true; 389 } 390 391 Base = N.getOperand(0); 392 Offset = N.getOperand(1); 393 return true; 394} 395 396bool 397ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op, SDValue N, 398 unsigned Scale, SDValue &Base, 399 SDValue &OffImm, SDValue &Offset) { 400 if (Scale == 4) { 401 SDValue TmpBase, TmpOffImm; 402 if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm)) 403 return false; // We want to select tLDRspi / tSTRspi instead. 404 if (N.getOpcode() == ARMISD::Wrapper && 405 N.getOperand(0).getOpcode() == ISD::TargetConstantPool) 406 return false; // We want to select tLDRpci instead. 407 } 408 409 if (N.getOpcode() != ISD::ADD) { 410 Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N; 411 Offset = CurDAG->getRegister(0, MVT::i32); 412 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 413 return true; 414 } 415 416 // Thumb does not have [sp, r] address mode. 417 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 418 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1)); 419 if ((LHSR && LHSR->getReg() == ARM::SP) || 420 (RHSR && RHSR->getReg() == ARM::SP)) { 421 Base = N; 422 Offset = CurDAG->getRegister(0, MVT::i32); 423 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 424 return true; 425 } 426 427 // If the RHS is + imm5 * scale, fold into addr mode. 428 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 429 int RHSC = (int)RHS->getZExtValue(); 430 if ((RHSC & (Scale-1)) == 0) { // The constant is implicitly multiplied. 431 RHSC /= Scale; 432 if (RHSC >= 0 && RHSC < 32) { 433 Base = N.getOperand(0); 434 Offset = CurDAG->getRegister(0, MVT::i32); 435 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 436 return true; 437 } 438 } 439 } 440 441 Base = N.getOperand(0); 442 Offset = N.getOperand(1); 443 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 444 return true; 445} 446 447bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue Op, SDValue N, 448 SDValue &Base, SDValue &OffImm, 449 SDValue &Offset) { 450 return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset); 451} 452 453bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue Op, SDValue N, 454 SDValue &Base, SDValue &OffImm, 455 SDValue &Offset) { 456 return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset); 457} 458 459bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue Op, SDValue N, 460 SDValue &Base, SDValue &OffImm, 461 SDValue &Offset) { 462 return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset); 463} 464 465bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N, 466 SDValue &Base, SDValue &OffImm) { 467 if (N.getOpcode() == ISD::FrameIndex) { 468 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 469 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 470 OffImm = CurDAG->getTargetConstant(0, MVT::i32); 471 return true; 472 } 473 474 if (N.getOpcode() != ISD::ADD) 475 return false; 476 477 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0)); 478 if (N.getOperand(0).getOpcode() == ISD::FrameIndex || 479 (LHSR && LHSR->getReg() == ARM::SP)) { 480 // If the RHS is + imm8 * scale, fold into addr mode. 481 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 482 int RHSC = (int)RHS->getZExtValue(); 483 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied. 484 RHSC >>= 2; 485 if (RHSC >= 0 && RHSC < 256) { 486 Base = N.getOperand(0); 487 if (Base.getOpcode() == ISD::FrameIndex) { 488 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 489 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 490 } 491 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32); 492 return true; 493 } 494 } 495 } 496 } 497 498 return false; 499} 500 501bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op, 502 SDValue N, 503 SDValue &BaseReg, 504 SDValue &ShReg, 505 SDValue &Opc) { 506 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); 507 508 // Don't match base register only case. That is matched to a separate 509 // lower complexity pattern with explicit register operand. 510 if (ShOpcVal == ARM_AM::no_shift) return false; 511 512 BaseReg = N.getOperand(0); 513 unsigned ShImmVal = 0; 514 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 515 ShReg = CurDAG->getRegister(0, MVT::i32); 516 ShImmVal = RHS->getZExtValue() & 31; 517 } else { 518 ShReg = N.getOperand(1); 519 } 520 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), 521 MVT::i32); 522 return true; 523} 524 525/// getAL - Returns a ARMCC::AL immediate node. 526static inline SDValue getAL(SelectionDAG *CurDAG) { 527 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32); 528} 529 530 531SDNode *ARMDAGToDAGISel::Select(SDValue Op) { 532 SDNode *N = Op.getNode(); 533 534 if (N->isMachineOpcode()) 535 return NULL; // Already selected. 536 537 switch (N->getOpcode()) { 538 default: break; 539 case ISD::Constant: { 540 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue(); 541 bool UseCP = true; 542 if (Subtarget->isThumb()) 543 UseCP = (Val > 255 && // MOV 544 ~Val > 255 && // MOV + MVN 545 !ARM_AM::isThumbImmShiftedVal(Val)); // MOV + LSL 546 else 547 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV 548 ARM_AM::getSOImmVal(~Val) == -1 && // MVN 549 !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs. 550 if (UseCP) { 551 SDValue CPIdx = 552 CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val), 553 TLI.getPointerTy()); 554 555 SDNode *ResNode; 556 if (Subtarget->isThumb()) 557 ResNode = CurDAG->getTargetNode(ARM::tLDRcp, MVT::i32, MVT::Other, 558 CPIdx, CurDAG->getEntryNode()); 559 else { 560 SDValue Ops[] = { 561 CPIdx, 562 CurDAG->getRegister(0, MVT::i32), 563 CurDAG->getTargetConstant(0, MVT::i32), 564 getAL(CurDAG), 565 CurDAG->getRegister(0, MVT::i32), 566 CurDAG->getEntryNode() 567 }; 568 ResNode=CurDAG->getTargetNode(ARM::LDRcp, MVT::i32, MVT::Other, Ops, 6); 569 } 570 ReplaceUses(Op, SDValue(ResNode, 0)); 571 return NULL; 572 } 573 574 // Other cases are autogenerated. 575 break; 576 } 577 case ISD::FrameIndex: { 578 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm. 579 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 580 SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); 581 if (Subtarget->isThumb()) 582 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI, 583 CurDAG->getTargetConstant(0, MVT::i32)); 584 else { 585 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), 586 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 587 CurDAG->getRegister(0, MVT::i32) }; 588 return CurDAG->SelectNodeTo(N, ARM::ADDri, MVT::i32, Ops, 5); 589 } 590 } 591 case ISD::ADD: { 592 // Select add sp, c to tADDhirr. 593 SDValue N0 = Op.getOperand(0); 594 SDValue N1 = Op.getOperand(1); 595 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(Op.getOperand(0)); 596 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(Op.getOperand(1)); 597 if (LHSR && LHSR->getReg() == ARM::SP) { 598 std::swap(N0, N1); 599 std::swap(LHSR, RHSR); 600 } 601 if (RHSR && RHSR->getReg() == ARM::SP) { 602 AddToISelQueue(N0); 603 AddToISelQueue(N1); 604 return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType(), N0, N1); 605 } 606 break; 607 } 608 case ISD::MUL: 609 if (Subtarget->isThumb()) 610 break; 611 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { 612 unsigned RHSV = C->getZExtValue(); 613 if (!RHSV) break; 614 if (isPowerOf2_32(RHSV-1)) { // 2^n+1? 615 SDValue V = Op.getOperand(0); 616 AddToISelQueue(V); 617 unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1)); 618 SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32), 619 CurDAG->getTargetConstant(ShImm, MVT::i32), 620 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 621 CurDAG->getRegister(0, MVT::i32) }; 622 return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7); 623 } 624 if (isPowerOf2_32(RHSV+1)) { // 2^n-1? 625 SDValue V = Op.getOperand(0); 626 AddToISelQueue(V); 627 unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV+1)); 628 SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32), 629 CurDAG->getTargetConstant(ShImm, MVT::i32), 630 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 631 CurDAG->getRegister(0, MVT::i32) }; 632 return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7); 633 } 634 } 635 break; 636 case ARMISD::FMRRD: 637 AddToISelQueue(Op.getOperand(0)); 638 return CurDAG->getTargetNode(ARM::FMRRD, MVT::i32, MVT::i32, 639 Op.getOperand(0), getAL(CurDAG), 640 CurDAG->getRegister(0, MVT::i32)); 641 case ISD::UMUL_LOHI: { 642 AddToISelQueue(Op.getOperand(0)); 643 AddToISelQueue(Op.getOperand(1)); 644 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 645 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 646 CurDAG->getRegister(0, MVT::i32) }; 647 return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32, Ops, 5); 648 } 649 case ISD::SMUL_LOHI: { 650 AddToISelQueue(Op.getOperand(0)); 651 AddToISelQueue(Op.getOperand(1)); 652 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1), 653 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32), 654 CurDAG->getRegister(0, MVT::i32) }; 655 return CurDAG->getTargetNode(ARM::SMULL, MVT::i32, MVT::i32, Ops, 5); 656 } 657 case ISD::LOAD: { 658 LoadSDNode *LD = cast<LoadSDNode>(Op); 659 ISD::MemIndexedMode AM = LD->getAddressingMode(); 660 MVT LoadedVT = LD->getMemoryVT(); 661 if (AM != ISD::UNINDEXED) { 662 SDValue Offset, AMOpc; 663 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); 664 unsigned Opcode = 0; 665 bool Match = false; 666 if (LoadedVT == MVT::i32 && 667 SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { 668 Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST; 669 Match = true; 670 } else if (LoadedVT == MVT::i16 && 671 SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { 672 Match = true; 673 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD) 674 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST) 675 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST); 676 } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) { 677 if (LD->getExtensionType() == ISD::SEXTLOAD) { 678 if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) { 679 Match = true; 680 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; 681 } 682 } else { 683 if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) { 684 Match = true; 685 Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST; 686 } 687 } 688 } 689 690 if (Match) { 691 SDValue Chain = LD->getChain(); 692 SDValue Base = LD->getBasePtr(); 693 AddToISelQueue(Chain); 694 AddToISelQueue(Base); 695 AddToISelQueue(Offset); 696 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), 697 CurDAG->getRegister(0, MVT::i32), Chain }; 698 return CurDAG->getTargetNode(Opcode, MVT::i32, MVT::i32, 699 MVT::Other, Ops, 6); 700 } 701 } 702 // Other cases are autogenerated. 703 break; 704 } 705 case ARMISD::BRCOND: { 706 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 707 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc) 708 // Pattern complexity = 6 cost = 1 size = 0 709 710 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc) 711 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc) 712 // Pattern complexity = 6 cost = 1 size = 0 713 714 unsigned Opc = Subtarget->isThumb() ? ARM::tBcc : ARM::Bcc; 715 SDValue Chain = Op.getOperand(0); 716 SDValue N1 = Op.getOperand(1); 717 SDValue N2 = Op.getOperand(2); 718 SDValue N3 = Op.getOperand(3); 719 SDValue InFlag = Op.getOperand(4); 720 assert(N1.getOpcode() == ISD::BasicBlock); 721 assert(N2.getOpcode() == ISD::Constant); 722 assert(N3.getOpcode() == ISD::Register); 723 724 AddToISelQueue(Chain); 725 AddToISelQueue(N1); 726 AddToISelQueue(InFlag); 727 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 728 cast<ConstantSDNode>(N2)->getZExtValue()), 729 MVT::i32); 730 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag }; 731 SDNode *ResNode = CurDAG->getTargetNode(Opc, MVT::Other, MVT::Flag, Ops, 5); 732 Chain = SDValue(ResNode, 0); 733 if (Op.getNode()->getNumValues() == 2) { 734 InFlag = SDValue(ResNode, 1); 735 ReplaceUses(SDValue(Op.getNode(), 1), InFlag); 736 } 737 ReplaceUses(SDValue(Op.getNode(), 0), SDValue(Chain.getNode(), Chain.getResNo())); 738 return NULL; 739 } 740 case ARMISD::CMOV: { 741 bool isThumb = Subtarget->isThumb(); 742 MVT VT = Op.getValueType(); 743 SDValue N0 = Op.getOperand(0); 744 SDValue N1 = Op.getOperand(1); 745 SDValue N2 = Op.getOperand(2); 746 SDValue N3 = Op.getOperand(3); 747 SDValue InFlag = Op.getOperand(4); 748 assert(N2.getOpcode() == ISD::Constant); 749 assert(N3.getOpcode() == ISD::Register); 750 751 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 752 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc) 753 // Pattern complexity = 18 cost = 1 size = 0 754 SDValue CPTmp0; 755 SDValue CPTmp1; 756 SDValue CPTmp2; 757 if (!isThumb && VT == MVT::i32 && 758 SelectShifterOperandReg(Op, N1, CPTmp0, CPTmp1, CPTmp2)) { 759 AddToISelQueue(N0); 760 AddToISelQueue(CPTmp0); 761 AddToISelQueue(CPTmp1); 762 AddToISelQueue(CPTmp2); 763 AddToISelQueue(InFlag); 764 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 765 cast<ConstantSDNode>(N2)->getZExtValue()), 766 MVT::i32); 767 SDValue Ops[] = { N0, CPTmp0, CPTmp1, CPTmp2, Tmp2, N3, InFlag }; 768 return CurDAG->SelectNodeTo(Op.getNode(), ARM::MOVCCs, MVT::i32, Ops, 7); 769 } 770 771 // Pattern: (ARMcmov:i32 GPR:i32:$false, 772 // (imm:i32)<<P:Predicate_so_imm>><<X:so_imm_XFORM>>:$true, 773 // (imm:i32):$cc) 774 // Emits: (MOVCCi:i32 GPR:i32:$false, 775 // (so_imm_XFORM:i32 (imm:i32):$true), (imm:i32):$cc) 776 // Pattern complexity = 10 cost = 1 size = 0 777 if (VT == MVT::i32 && 778 N3.getOpcode() == ISD::Constant && 779 Predicate_so_imm(N3.getNode())) { 780 AddToISelQueue(N0); 781 AddToISelQueue(InFlag); 782 SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned) 783 cast<ConstantSDNode>(N1)->getZExtValue()), 784 MVT::i32); 785 Tmp1 = Transform_so_imm_XFORM(Tmp1.getNode()); 786 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 787 cast<ConstantSDNode>(N2)->getZExtValue()), 788 MVT::i32); 789 SDValue Ops[] = { N0, Tmp1, Tmp2, N3, InFlag }; 790 return CurDAG->SelectNodeTo(Op.getNode(), ARM::MOVCCi, MVT::i32, Ops, 5); 791 } 792 793 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 794 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 795 // Pattern complexity = 6 cost = 1 size = 0 796 // 797 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 798 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc) 799 // Pattern complexity = 6 cost = 11 size = 0 800 // 801 // Also FCPYScc and FCPYDcc. 802 AddToISelQueue(N0); 803 AddToISelQueue(N1); 804 AddToISelQueue(InFlag); 805 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 806 cast<ConstantSDNode>(N2)->getZExtValue()), 807 MVT::i32); 808 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 809 unsigned Opc = 0; 810 switch (VT.getSimpleVT()) { 811 default: assert(false && "Illegal conditional move type!"); 812 break; 813 case MVT::i32: 814 Opc = isThumb ? ARM::tMOVCCr : ARM::MOVCCr; 815 break; 816 case MVT::f32: 817 Opc = ARM::FCPYScc; 818 break; 819 case MVT::f64: 820 Opc = ARM::FCPYDcc; 821 break; 822 } 823 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); 824 } 825 case ARMISD::CNEG: { 826 MVT VT = Op.getValueType(); 827 SDValue N0 = Op.getOperand(0); 828 SDValue N1 = Op.getOperand(1); 829 SDValue N2 = Op.getOperand(2); 830 SDValue N3 = Op.getOperand(3); 831 SDValue InFlag = Op.getOperand(4); 832 assert(N2.getOpcode() == ISD::Constant); 833 assert(N3.getOpcode() == ISD::Register); 834 835 AddToISelQueue(N0); 836 AddToISelQueue(N1); 837 AddToISelQueue(InFlag); 838 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned) 839 cast<ConstantSDNode>(N2)->getZExtValue()), 840 MVT::i32); 841 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag }; 842 unsigned Opc = 0; 843 switch (VT.getSimpleVT()) { 844 default: assert(false && "Illegal conditional move type!"); 845 break; 846 case MVT::f32: 847 Opc = ARM::FNEGScc; 848 break; 849 case MVT::f64: 850 Opc = ARM::FNEGDcc; 851 break; 852 } 853 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5); 854 } 855 } 856 return SelectCode(Op); 857} 858 859/// createARMISelDag - This pass converts a legalized DAG into a 860/// ARM-specific DAG, ready for instruction scheduling. 861/// 862FunctionPass *llvm::createARMISelDag(ARMTargetMachine &TM) { 863 return new ARMDAGToDAGISel(TM); 864} 865