1 //===-- HexagonISelDAGToDAG.cpp - A dag to dag inst selector for Hexagon --===// 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 Hexagon target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "Hexagon.h" 15 #include "HexagonISelLowering.h" 16 #include "HexagonMachineFunctionInfo.h" 17 #include "HexagonTargetMachine.h" 18 #include "llvm/CodeGen/FunctionLoweringInfo.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/SelectionDAGISel.h" 21 #include "llvm/IR/Intrinsics.h" 22 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Support/Debug.h" 24 using namespace llvm; 25 26 #define DEBUG_TYPE "hexagon-isel" 27 28 static 29 cl::opt<unsigned> 30 MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders", 31 cl::Hidden, cl::init(2), 32 cl::desc("Maximum number of uses of a global address such that we still us a" 33 "constant extended instruction")); 34 35 //===----------------------------------------------------------------------===// 36 // Instruction Selector Implementation 37 //===----------------------------------------------------------------------===// 38 39 //===--------------------------------------------------------------------===// 40 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine 41 /// instructions for SelectionDAG operations. 42 /// 43 namespace { 44 class HexagonDAGToDAGISel : public SelectionDAGISel { 45 const HexagonTargetMachine &HTM; 46 const HexagonSubtarget *HST; 47 const HexagonInstrInfo *HII; 48 const HexagonRegisterInfo *HRI; 49 public: 50 explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm, 51 CodeGenOpt::Level OptLevel) 52 : SelectionDAGISel(tm, OptLevel), HTM(tm), HST(nullptr), HII(nullptr), 53 HRI(nullptr) {} 54 55 bool runOnMachineFunction(MachineFunction &MF) override { 56 // Reset the subtarget each time through. 57 HST = &MF.getSubtarget<HexagonSubtarget>(); 58 HII = HST->getInstrInfo(); 59 HRI = HST->getRegisterInfo(); 60 SelectionDAGISel::runOnMachineFunction(MF); 61 return true; 62 } 63 64 virtual void PreprocessISelDAG() override; 65 virtual void EmitFunctionEntryCode() override; 66 67 void Select(SDNode *N) override; 68 69 // Complex Pattern Selectors. 70 inline bool SelectAddrGA(SDValue &N, SDValue &R); 71 inline bool SelectAddrGP(SDValue &N, SDValue &R); 72 bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP); 73 bool SelectAddrFI(SDValue &N, SDValue &R); 74 75 const char *getPassName() const override { 76 return "Hexagon DAG->DAG Pattern Instruction Selection"; 77 } 78 79 // Generate a machine instruction node corresponding to the circ/brev 80 // load intrinsic. 81 MachineSDNode *LoadInstrForLoadIntrinsic(SDNode *IntN); 82 // Given the circ/brev load intrinsic and the already generated machine 83 // instruction, generate the appropriate store (that is a part of the 84 // intrinsic's functionality). 85 SDNode *StoreInstrForLoadIntrinsic(MachineSDNode *LoadN, SDNode *IntN); 86 87 void SelectFrameIndex(SDNode *N); 88 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 89 /// inline asm expressions. 90 bool SelectInlineAsmMemoryOperand(const SDValue &Op, 91 unsigned ConstraintID, 92 std::vector<SDValue> &OutOps) override; 93 bool tryLoadOfLoadIntrinsic(LoadSDNode *N); 94 void SelectLoad(SDNode *N); 95 void SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl); 96 void SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl); 97 void SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl); 98 void SelectStore(SDNode *N); 99 void SelectSHL(SDNode *N); 100 void SelectMul(SDNode *N); 101 void SelectZeroExtend(SDNode *N); 102 void SelectIntrinsicWChain(SDNode *N); 103 void SelectIntrinsicWOChain(SDNode *N); 104 void SelectConstant(SDNode *N); 105 void SelectConstantFP(SDNode *N); 106 void SelectAdd(SDNode *N); 107 void SelectBitcast(SDNode *N); 108 void SelectBitOp(SDNode *N); 109 110 // XformMskToBitPosU5Imm - Returns the bit position which 111 // the single bit 32 bit mask represents. 112 // Used in Clr and Set bit immediate memops. 113 SDValue XformMskToBitPosU5Imm(uint32_t Imm, const SDLoc &DL) { 114 int32_t bitPos; 115 bitPos = Log2_32(Imm); 116 assert(bitPos >= 0 && bitPos < 32 && 117 "Constant out of range for 32 BitPos Memops"); 118 return CurDAG->getTargetConstant(bitPos, DL, MVT::i32); 119 } 120 121 // XformMskToBitPosU4Imm - Returns the bit position which the single-bit 122 // 16 bit mask represents. Used in Clr and Set bit immediate memops. 123 SDValue XformMskToBitPosU4Imm(uint16_t Imm, const SDLoc &DL) { 124 return XformMskToBitPosU5Imm(Imm, DL); 125 } 126 127 // XformMskToBitPosU3Imm - Returns the bit position which the single-bit 128 // 8 bit mask represents. Used in Clr and Set bit immediate memops. 129 SDValue XformMskToBitPosU3Imm(uint8_t Imm, const SDLoc &DL) { 130 return XformMskToBitPosU5Imm(Imm, DL); 131 } 132 133 // Return true if there is exactly one bit set in V, i.e., if V is one of the 134 // following integers: 2^0, 2^1, ..., 2^31. 135 bool ImmIsSingleBit(uint32_t v) const { 136 return isPowerOf2_32(v); 137 } 138 139 // XformM5ToU5Imm - Return a target constant with the specified value, of 140 // type i32 where the negative literal is transformed into a positive literal 141 // for use in -= memops. 142 inline SDValue XformM5ToU5Imm(signed Imm, const SDLoc &DL) { 143 assert((Imm >= -31 && Imm <= -1) && "Constant out of range for Memops"); 144 return CurDAG->getTargetConstant(-Imm, DL, MVT::i32); 145 } 146 147 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range 148 // [1..128], used in cmpb.gtu instructions. 149 inline SDValue XformU7ToU7M1Imm(signed Imm, const SDLoc &DL) { 150 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op"); 151 return CurDAG->getTargetConstant(Imm - 1, DL, MVT::i8); 152 } 153 154 // XformS8ToS8M1Imm - Return a target constant decremented by 1. 155 inline SDValue XformSToSM1Imm(signed Imm, const SDLoc &DL) { 156 return CurDAG->getTargetConstant(Imm - 1, DL, MVT::i32); 157 } 158 159 // XformU8ToU8M1Imm - Return a target constant decremented by 1. 160 inline SDValue XformUToUM1Imm(unsigned Imm, const SDLoc &DL) { 161 assert((Imm >= 1) && "Cannot decrement unsigned int less than 1"); 162 return CurDAG->getTargetConstant(Imm - 1, DL, MVT::i32); 163 } 164 165 // XformSToSM2Imm - Return a target constant decremented by 2. 166 inline SDValue XformSToSM2Imm(unsigned Imm, const SDLoc &DL) { 167 return CurDAG->getTargetConstant(Imm - 2, DL, MVT::i32); 168 } 169 170 // XformSToSM3Imm - Return a target constant decremented by 3. 171 inline SDValue XformSToSM3Imm(unsigned Imm, const SDLoc &DL) { 172 return CurDAG->getTargetConstant(Imm - 3, DL, MVT::i32); 173 } 174 175 // Include the pieces autogenerated from the target description. 176 #include "HexagonGenDAGISel.inc" 177 178 private: 179 bool isValueExtension(const SDValue &Val, unsigned FromBits, SDValue &Src); 180 bool isAlignedMemNode(const MemSDNode *N) const; 181 }; // end HexagonDAGToDAGISel 182 } // end anonymous namespace 183 184 185 /// createHexagonISelDag - This pass converts a legalized DAG into a 186 /// Hexagon-specific DAG, ready for instruction scheduling. 187 /// 188 namespace llvm { 189 FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, 190 CodeGenOpt::Level OptLevel) { 191 return new HexagonDAGToDAGISel(TM, OptLevel); 192 } 193 } 194 195 // Intrinsics that return a a predicate. 196 static bool doesIntrinsicReturnPredicate(unsigned ID) { 197 switch (ID) { 198 default: 199 return false; 200 case Intrinsic::hexagon_C2_cmpeq: 201 case Intrinsic::hexagon_C2_cmpgt: 202 case Intrinsic::hexagon_C2_cmpgtu: 203 case Intrinsic::hexagon_C2_cmpgtup: 204 case Intrinsic::hexagon_C2_cmpgtp: 205 case Intrinsic::hexagon_C2_cmpeqp: 206 case Intrinsic::hexagon_C2_bitsset: 207 case Intrinsic::hexagon_C2_bitsclr: 208 case Intrinsic::hexagon_C2_cmpeqi: 209 case Intrinsic::hexagon_C2_cmpgti: 210 case Intrinsic::hexagon_C2_cmpgtui: 211 case Intrinsic::hexagon_C2_cmpgei: 212 case Intrinsic::hexagon_C2_cmpgeui: 213 case Intrinsic::hexagon_C2_cmplt: 214 case Intrinsic::hexagon_C2_cmpltu: 215 case Intrinsic::hexagon_C2_bitsclri: 216 case Intrinsic::hexagon_C2_and: 217 case Intrinsic::hexagon_C2_or: 218 case Intrinsic::hexagon_C2_xor: 219 case Intrinsic::hexagon_C2_andn: 220 case Intrinsic::hexagon_C2_not: 221 case Intrinsic::hexagon_C2_orn: 222 case Intrinsic::hexagon_C2_pxfer_map: 223 case Intrinsic::hexagon_C2_any8: 224 case Intrinsic::hexagon_C2_all8: 225 case Intrinsic::hexagon_A2_vcmpbeq: 226 case Intrinsic::hexagon_A2_vcmpbgtu: 227 case Intrinsic::hexagon_A2_vcmpheq: 228 case Intrinsic::hexagon_A2_vcmphgt: 229 case Intrinsic::hexagon_A2_vcmphgtu: 230 case Intrinsic::hexagon_A2_vcmpweq: 231 case Intrinsic::hexagon_A2_vcmpwgt: 232 case Intrinsic::hexagon_A2_vcmpwgtu: 233 case Intrinsic::hexagon_C2_tfrrp: 234 case Intrinsic::hexagon_S2_tstbit_i: 235 case Intrinsic::hexagon_S2_tstbit_r: 236 return true; 237 } 238 } 239 240 void HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl) { 241 SDValue Chain = LD->getChain(); 242 SDValue Base = LD->getBasePtr(); 243 SDValue Offset = LD->getOffset(); 244 int32_t Inc = cast<ConstantSDNode>(Offset.getNode())->getSExtValue(); 245 EVT LoadedVT = LD->getMemoryVT(); 246 unsigned Opcode = 0; 247 248 // Check for zero extended loads. Treat any-extend loads as zero extended 249 // loads. 250 ISD::LoadExtType ExtType = LD->getExtensionType(); 251 bool IsZeroExt = (ExtType == ISD::ZEXTLOAD || ExtType == ISD::EXTLOAD); 252 bool IsValidInc = HII->isValidAutoIncImm(LoadedVT, Inc); 253 254 assert(LoadedVT.isSimple()); 255 switch (LoadedVT.getSimpleVT().SimpleTy) { 256 case MVT::i8: 257 if (IsZeroExt) 258 Opcode = IsValidInc ? Hexagon::L2_loadrub_pi : Hexagon::L2_loadrub_io; 259 else 260 Opcode = IsValidInc ? Hexagon::L2_loadrb_pi : Hexagon::L2_loadrb_io; 261 break; 262 case MVT::i16: 263 if (IsZeroExt) 264 Opcode = IsValidInc ? Hexagon::L2_loadruh_pi : Hexagon::L2_loadruh_io; 265 else 266 Opcode = IsValidInc ? Hexagon::L2_loadrh_pi : Hexagon::L2_loadrh_io; 267 break; 268 case MVT::i32: 269 Opcode = IsValidInc ? Hexagon::L2_loadri_pi : Hexagon::L2_loadri_io; 270 break; 271 case MVT::i64: 272 Opcode = IsValidInc ? Hexagon::L2_loadrd_pi : Hexagon::L2_loadrd_io; 273 break; 274 // 64B 275 case MVT::v64i8: 276 case MVT::v32i16: 277 case MVT::v16i32: 278 case MVT::v8i64: 279 if (isAlignedMemNode(LD)) 280 Opcode = IsValidInc ? Hexagon::V6_vL32b_pi : Hexagon::V6_vL32b_ai; 281 else 282 Opcode = IsValidInc ? Hexagon::V6_vL32Ub_pi : Hexagon::V6_vL32Ub_ai; 283 break; 284 // 128B 285 case MVT::v128i8: 286 case MVT::v64i16: 287 case MVT::v32i32: 288 case MVT::v16i64: 289 if (isAlignedMemNode(LD)) 290 Opcode = IsValidInc ? Hexagon::V6_vL32b_pi_128B 291 : Hexagon::V6_vL32b_ai_128B; 292 else 293 Opcode = IsValidInc ? Hexagon::V6_vL32Ub_pi_128B 294 : Hexagon::V6_vL32Ub_ai_128B; 295 break; 296 default: 297 llvm_unreachable("Unexpected memory type in indexed load"); 298 } 299 300 SDValue IncV = CurDAG->getTargetConstant(Inc, dl, MVT::i32); 301 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 302 MemOp[0] = LD->getMemOperand(); 303 304 auto getExt64 = [this,ExtType] (MachineSDNode *N, const SDLoc &dl) 305 -> MachineSDNode* { 306 if (ExtType == ISD::ZEXTLOAD || ExtType == ISD::EXTLOAD) { 307 SDValue Zero = CurDAG->getTargetConstant(0, dl, MVT::i32); 308 return CurDAG->getMachineNode(Hexagon::A4_combineir, dl, MVT::i64, 309 Zero, SDValue(N, 0)); 310 } 311 if (ExtType == ISD::SEXTLOAD) 312 return CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64, 313 SDValue(N, 0)); 314 return N; 315 }; 316 317 // Loaded value Next address Chain 318 SDValue From[3] = { SDValue(LD,0), SDValue(LD,1), SDValue(LD,2) }; 319 SDValue To[3]; 320 321 EVT ValueVT = LD->getValueType(0); 322 if (ValueVT == MVT::i64 && ExtType != ISD::NON_EXTLOAD) { 323 // A load extending to i64 will actually produce i32, which will then 324 // need to be extended to i64. 325 assert(LoadedVT.getSizeInBits() <= 32); 326 ValueVT = MVT::i32; 327 } 328 329 if (IsValidInc) { 330 MachineSDNode *L = CurDAG->getMachineNode(Opcode, dl, ValueVT, 331 MVT::i32, MVT::Other, Base, 332 IncV, Chain); 333 L->setMemRefs(MemOp, MemOp+1); 334 To[1] = SDValue(L, 1); // Next address. 335 To[2] = SDValue(L, 2); // Chain. 336 // Handle special case for extension to i64. 337 if (LD->getValueType(0) == MVT::i64) 338 L = getExt64(L, dl); 339 To[0] = SDValue(L, 0); // Loaded (extended) value. 340 } else { 341 SDValue Zero = CurDAG->getTargetConstant(0, dl, MVT::i32); 342 MachineSDNode *L = CurDAG->getMachineNode(Opcode, dl, ValueVT, MVT::Other, 343 Base, Zero, Chain); 344 L->setMemRefs(MemOp, MemOp+1); 345 To[2] = SDValue(L, 1); // Chain. 346 MachineSDNode *A = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32, 347 Base, IncV); 348 To[1] = SDValue(A, 0); // Next address. 349 // Handle special case for extension to i64. 350 if (LD->getValueType(0) == MVT::i64) 351 L = getExt64(L, dl); 352 To[0] = SDValue(L, 0); // Loaded (extended) value. 353 } 354 ReplaceUses(From, To, 3); 355 CurDAG->RemoveDeadNode(LD); 356 } 357 358 359 MachineSDNode *HexagonDAGToDAGISel::LoadInstrForLoadIntrinsic(SDNode *IntN) { 360 if (IntN->getOpcode() != ISD::INTRINSIC_W_CHAIN) 361 return nullptr; 362 363 SDLoc dl(IntN); 364 unsigned IntNo = cast<ConstantSDNode>(IntN->getOperand(1))->getZExtValue(); 365 366 static std::map<unsigned,unsigned> LoadPciMap = { 367 { Intrinsic::hexagon_circ_ldb, Hexagon::L2_loadrb_pci }, 368 { Intrinsic::hexagon_circ_ldub, Hexagon::L2_loadrub_pci }, 369 { Intrinsic::hexagon_circ_ldh, Hexagon::L2_loadrh_pci }, 370 { Intrinsic::hexagon_circ_lduh, Hexagon::L2_loadruh_pci }, 371 { Intrinsic::hexagon_circ_ldw, Hexagon::L2_loadri_pci }, 372 { Intrinsic::hexagon_circ_ldd, Hexagon::L2_loadrd_pci }, 373 }; 374 auto FLC = LoadPciMap.find(IntNo); 375 if (FLC != LoadPciMap.end()) { 376 SDNode *Mod = CurDAG->getMachineNode(Hexagon::A2_tfrrcr, dl, MVT::i32, 377 IntN->getOperand(4)); 378 EVT ValTy = (IntNo == Intrinsic::hexagon_circ_ldd) ? MVT::i64 : MVT::i32; 379 EVT RTys[] = { ValTy, MVT::i32, MVT::Other }; 380 // Operands: { Base, Increment, Modifier, Chain } 381 auto Inc = cast<ConstantSDNode>(IntN->getOperand(5)); 382 SDValue I = CurDAG->getTargetConstant(Inc->getSExtValue(), dl, MVT::i32); 383 MachineSDNode *Res = CurDAG->getMachineNode(FLC->second, dl, RTys, 384 { IntN->getOperand(2), I, SDValue(Mod,0), IntN->getOperand(0) }); 385 return Res; 386 } 387 388 static std::map<unsigned,unsigned> LoadPbrMap = { 389 { Intrinsic::hexagon_brev_ldb, Hexagon::L2_loadrb_pbr }, 390 { Intrinsic::hexagon_brev_ldub, Hexagon::L2_loadrub_pbr }, 391 { Intrinsic::hexagon_brev_ldh, Hexagon::L2_loadrh_pbr }, 392 { Intrinsic::hexagon_brev_lduh, Hexagon::L2_loadruh_pbr }, 393 { Intrinsic::hexagon_brev_ldw, Hexagon::L2_loadri_pbr }, 394 { Intrinsic::hexagon_brev_ldd, Hexagon::L2_loadrd_pbr }, 395 }; 396 auto FLB = LoadPbrMap.find(IntNo); 397 if (FLB != LoadPbrMap.end()) { 398 SDNode *Mod = CurDAG->getMachineNode(Hexagon::A2_tfrrcr, dl, MVT::i32, 399 IntN->getOperand(4)); 400 EVT ValTy = (IntNo == Intrinsic::hexagon_brev_ldd) ? MVT::i64 : MVT::i32; 401 EVT RTys[] = { ValTy, MVT::i32, MVT::Other }; 402 // Operands: { Base, Modifier, Chain } 403 MachineSDNode *Res = CurDAG->getMachineNode(FLB->second, dl, RTys, 404 { IntN->getOperand(2), SDValue(Mod,0), IntN->getOperand(0) }); 405 return Res; 406 } 407 408 return nullptr; 409 } 410 411 SDNode *HexagonDAGToDAGISel::StoreInstrForLoadIntrinsic(MachineSDNode *LoadN, 412 SDNode *IntN) { 413 // The "LoadN" is just a machine load instruction. The intrinsic also 414 // involves storing it. Generate an appropriate store to the location 415 // given in the intrinsic's operand(3). 416 uint64_t F = HII->get(LoadN->getMachineOpcode()).TSFlags; 417 unsigned SizeBits = (F >> HexagonII::MemAccessSizePos) & 418 HexagonII::MemAccesSizeMask; 419 unsigned Size = 1U << (SizeBits-1); 420 421 SDLoc dl(IntN); 422 MachinePointerInfo PI; 423 SDValue TS; 424 SDValue Loc = IntN->getOperand(3); 425 426 if (Size >= 4) 427 TS = CurDAG->getStore(SDValue(LoadN,2), dl, SDValue(LoadN, 0), Loc, PI, 428 false, false, Size); 429 else 430 TS = CurDAG->getTruncStore(SDValue(LoadN,2), dl, SDValue(LoadN,0), Loc, PI, 431 MVT::getIntegerVT(Size*8), false, false, Size); 432 433 SDNode *StoreN; 434 { 435 HandleSDNode Handle(TS); 436 SelectStore(TS.getNode()); 437 StoreN = Handle.getValue().getNode(); 438 } 439 440 // Load's results are { Loaded value, Updated pointer, Chain } 441 ReplaceUses(SDValue(IntN, 0), SDValue(LoadN, 1)); 442 ReplaceUses(SDValue(IntN, 1), SDValue(StoreN, 0)); 443 return StoreN; 444 } 445 446 bool HexagonDAGToDAGISel::tryLoadOfLoadIntrinsic(LoadSDNode *N) { 447 // The intrinsics for load circ/brev perform two operations: 448 // 1. Load a value V from the specified location, using the addressing 449 // mode corresponding to the intrinsic. 450 // 2. Store V into a specified location. This location is typically a 451 // local, temporary object. 452 // In many cases, the program using these intrinsics will immediately 453 // load V again from the local object. In those cases, when certain 454 // conditions are met, the last load can be removed. 455 // This function identifies and optimizes this pattern. If the pattern 456 // cannot be optimized, it returns nullptr, which will cause the load 457 // to be selected separately from the intrinsic (which will be handled 458 // in SelectIntrinsicWChain). 459 460 SDValue Ch = N->getOperand(0); 461 SDValue Loc = N->getOperand(1); 462 463 // Assume that the load and the intrinsic are connected directly with a 464 // chain: 465 // t1: i32,ch = int.load ..., ..., ..., Loc, ... // <-- C 466 // t2: i32,ch = load t1:1, Loc, ... 467 SDNode *C = Ch.getNode(); 468 469 if (C->getOpcode() != ISD::INTRINSIC_W_CHAIN) 470 return false; 471 472 // The second load can only be eliminated if its extension type matches 473 // that of the load instruction corresponding to the intrinsic. The user 474 // can provide an address of an unsigned variable to store the result of 475 // a sign-extending intrinsic into (or the other way around). 476 ISD::LoadExtType IntExt; 477 switch (cast<ConstantSDNode>(C->getOperand(1))->getZExtValue()) { 478 case Intrinsic::hexagon_brev_ldub: 479 case Intrinsic::hexagon_brev_lduh: 480 case Intrinsic::hexagon_circ_ldub: 481 case Intrinsic::hexagon_circ_lduh: 482 IntExt = ISD::ZEXTLOAD; 483 break; 484 case Intrinsic::hexagon_brev_ldw: 485 case Intrinsic::hexagon_brev_ldd: 486 case Intrinsic::hexagon_circ_ldw: 487 case Intrinsic::hexagon_circ_ldd: 488 IntExt = ISD::NON_EXTLOAD; 489 break; 490 default: 491 IntExt = ISD::SEXTLOAD; 492 break; 493 } 494 if (N->getExtensionType() != IntExt) 495 return false; 496 497 // Make sure the target location for the loaded value in the load intrinsic 498 // is the location from which LD (or N) is loading. 499 if (C->getNumOperands() < 4 || Loc.getNode() != C->getOperand(3).getNode()) 500 return false; 501 502 if (MachineSDNode *L = LoadInstrForLoadIntrinsic(C)) { 503 SDNode *S = StoreInstrForLoadIntrinsic(L, C); 504 SDValue F[] = { SDValue(N,0), SDValue(N,1), SDValue(C,0), SDValue(C,1) }; 505 SDValue T[] = { SDValue(L,0), SDValue(S,0), SDValue(L,1), SDValue(S,0) }; 506 ReplaceUses(F, T, array_lengthof(T)); 507 // This transformation will leave the intrinsic dead. If it remains in 508 // the DAG, the selection code will see it again, but without the load, 509 // and it will generate a store that is normally required for it. 510 CurDAG->RemoveDeadNode(C); 511 return true; 512 } 513 514 return false; 515 } 516 517 void HexagonDAGToDAGISel::SelectLoad(SDNode *N) { 518 SDLoc dl(N); 519 LoadSDNode *LD = cast<LoadSDNode>(N); 520 ISD::MemIndexedMode AM = LD->getAddressingMode(); 521 522 // Handle indexed loads. 523 if (AM != ISD::UNINDEXED) { 524 SelectIndexedLoad(LD, dl); 525 return; 526 } 527 528 // Handle patterns using circ/brev load intrinsics. 529 if (tryLoadOfLoadIntrinsic(LD)) 530 return; 531 532 SelectCode(LD); 533 } 534 535 void HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl) { 536 SDValue Chain = ST->getChain(); 537 SDValue Base = ST->getBasePtr(); 538 SDValue Offset = ST->getOffset(); 539 SDValue Value = ST->getValue(); 540 // Get the constant value. 541 int32_t Inc = cast<ConstantSDNode>(Offset.getNode())->getSExtValue(); 542 EVT StoredVT = ST->getMemoryVT(); 543 EVT ValueVT = Value.getValueType(); 544 545 bool IsValidInc = HII->isValidAutoIncImm(StoredVT, Inc); 546 unsigned Opcode = 0; 547 548 assert(StoredVT.isSimple()); 549 switch (StoredVT.getSimpleVT().SimpleTy) { 550 case MVT::i8: 551 Opcode = IsValidInc ? Hexagon::S2_storerb_pi : Hexagon::S2_storerb_io; 552 break; 553 case MVT::i16: 554 Opcode = IsValidInc ? Hexagon::S2_storerh_pi : Hexagon::S2_storerh_io; 555 break; 556 case MVT::i32: 557 Opcode = IsValidInc ? Hexagon::S2_storeri_pi : Hexagon::S2_storeri_io; 558 break; 559 case MVT::i64: 560 Opcode = IsValidInc ? Hexagon::S2_storerd_pi : Hexagon::S2_storerd_io; 561 break; 562 // 64B 563 case MVT::v64i8: 564 case MVT::v32i16: 565 case MVT::v16i32: 566 case MVT::v8i64: 567 if (isAlignedMemNode(ST)) 568 Opcode = IsValidInc ? Hexagon::V6_vS32b_pi : Hexagon::V6_vS32b_ai; 569 else 570 Opcode = IsValidInc ? Hexagon::V6_vS32Ub_pi : Hexagon::V6_vS32Ub_ai; 571 break; 572 // 128B 573 case MVT::v128i8: 574 case MVT::v64i16: 575 case MVT::v32i32: 576 case MVT::v16i64: 577 if (isAlignedMemNode(ST)) 578 Opcode = IsValidInc ? Hexagon::V6_vS32b_pi_128B 579 : Hexagon::V6_vS32b_ai_128B; 580 else 581 Opcode = IsValidInc ? Hexagon::V6_vS32Ub_pi_128B 582 : Hexagon::V6_vS32Ub_ai_128B; 583 break; 584 default: 585 llvm_unreachable("Unexpected memory type in indexed store"); 586 } 587 588 if (ST->isTruncatingStore() && ValueVT.getSizeInBits() == 64) { 589 assert(StoredVT.getSizeInBits() < 64 && "Not a truncating store"); 590 Value = CurDAG->getTargetExtractSubreg(Hexagon::subreg_loreg, 591 dl, MVT::i32, Value); 592 } 593 594 SDValue IncV = CurDAG->getTargetConstant(Inc, dl, MVT::i32); 595 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 596 MemOp[0] = ST->getMemOperand(); 597 598 // Next address Chain 599 SDValue From[2] = { SDValue(ST,0), SDValue(ST,1) }; 600 SDValue To[2]; 601 602 if (IsValidInc) { 603 // Build post increment store. 604 SDValue Ops[] = { Base, IncV, Value, Chain }; 605 MachineSDNode *S = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::Other, 606 Ops); 607 S->setMemRefs(MemOp, MemOp + 1); 608 To[0] = SDValue(S, 0); 609 To[1] = SDValue(S, 1); 610 } else { 611 SDValue Zero = CurDAG->getTargetConstant(0, dl, MVT::i32); 612 SDValue Ops[] = { Base, Zero, Value, Chain }; 613 MachineSDNode *S = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops); 614 S->setMemRefs(MemOp, MemOp + 1); 615 To[1] = SDValue(S, 0); 616 MachineSDNode *A = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32, 617 Base, IncV); 618 To[0] = SDValue(A, 0); 619 } 620 621 ReplaceUses(From, To, 2); 622 CurDAG->RemoveDeadNode(ST); 623 } 624 625 void HexagonDAGToDAGISel::SelectStore(SDNode *N) { 626 SDLoc dl(N); 627 StoreSDNode *ST = cast<StoreSDNode>(N); 628 ISD::MemIndexedMode AM = ST->getAddressingMode(); 629 630 // Handle indexed stores. 631 if (AM != ISD::UNINDEXED) { 632 SelectIndexedStore(ST, dl); 633 return; 634 } 635 636 SelectCode(ST); 637 } 638 639 void HexagonDAGToDAGISel::SelectMul(SDNode *N) { 640 SDLoc dl(N); 641 642 // 643 // %conv.i = sext i32 %tmp1 to i64 644 // %conv2.i = sext i32 %add to i64 645 // %mul.i = mul nsw i64 %conv2.i, %conv.i 646 // 647 // --- match with the following --- 648 // 649 // %mul.i = mpy (%tmp1, %add) 650 // 651 652 if (N->getValueType(0) == MVT::i64) { 653 // Shifting a i64 signed multiply. 654 SDValue MulOp0 = N->getOperand(0); 655 SDValue MulOp1 = N->getOperand(1); 656 657 SDValue OP0; 658 SDValue OP1; 659 660 // Handle sign_extend and sextload. 661 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) { 662 SDValue Sext0 = MulOp0.getOperand(0); 663 if (Sext0.getNode()->getValueType(0) != MVT::i32) { 664 SelectCode(N); 665 return; 666 } 667 668 OP0 = Sext0; 669 } else if (MulOp0.getOpcode() == ISD::LOAD) { 670 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode()); 671 if (LD->getMemoryVT() != MVT::i32 || 672 LD->getExtensionType() != ISD::SEXTLOAD || 673 LD->getAddressingMode() != ISD::UNINDEXED) { 674 SelectCode(N); 675 return; 676 } 677 678 SDValue Chain = LD->getChain(); 679 SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32); 680 OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32, 681 MVT::Other, 682 LD->getBasePtr(), TargetConst0, 683 Chain), 0); 684 } else { 685 SelectCode(N); 686 return; 687 } 688 689 // Same goes for the second operand. 690 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) { 691 SDValue Sext1 = MulOp1.getOperand(0); 692 if (Sext1.getNode()->getValueType(0) != MVT::i32) { 693 SelectCode(N); 694 return; 695 } 696 697 OP1 = Sext1; 698 } else if (MulOp1.getOpcode() == ISD::LOAD) { 699 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode()); 700 if (LD->getMemoryVT() != MVT::i32 || 701 LD->getExtensionType() != ISD::SEXTLOAD || 702 LD->getAddressingMode() != ISD::UNINDEXED) { 703 SelectCode(N); 704 return; 705 } 706 707 SDValue Chain = LD->getChain(); 708 SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32); 709 OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32, 710 MVT::Other, 711 LD->getBasePtr(), TargetConst0, 712 Chain), 0); 713 } else { 714 SelectCode(N); 715 return; 716 } 717 718 // Generate a mpy instruction. 719 SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl, MVT::i64, 720 OP0, OP1); 721 ReplaceNode(N, Result); 722 return; 723 } 724 725 SelectCode(N); 726 } 727 728 void HexagonDAGToDAGISel::SelectSHL(SDNode *N) { 729 SDLoc dl(N); 730 if (N->getValueType(0) == MVT::i32) { 731 SDValue Shl_0 = N->getOperand(0); 732 SDValue Shl_1 = N->getOperand(1); 733 // RHS is const. 734 if (Shl_1.getOpcode() == ISD::Constant) { 735 if (Shl_0.getOpcode() == ISD::MUL) { 736 SDValue Mul_0 = Shl_0.getOperand(0); // Val 737 SDValue Mul_1 = Shl_0.getOperand(1); // Const 738 // RHS of mul is const. 739 if (Mul_1.getOpcode() == ISD::Constant) { 740 int32_t ShlConst = 741 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue(); 742 int32_t MulConst = 743 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue(); 744 int32_t ValConst = MulConst << ShlConst; 745 SDValue Val = CurDAG->getTargetConstant(ValConst, dl, 746 MVT::i32); 747 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode())) 748 if (isInt<9>(CN->getSExtValue())) { 749 SDNode* Result = 750 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, 751 MVT::i32, Mul_0, Val); 752 ReplaceNode(N, Result); 753 return; 754 } 755 756 } 757 } else if (Shl_0.getOpcode() == ISD::SUB) { 758 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0 759 SDValue Sub_1 = Shl_0.getOperand(1); // Val 760 if (Sub_0.getOpcode() == ISD::Constant) { 761 int32_t SubConst = 762 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue(); 763 if (SubConst == 0) { 764 if (Sub_1.getOpcode() == ISD::SHL) { 765 SDValue Shl2_0 = Sub_1.getOperand(0); // Val 766 SDValue Shl2_1 = Sub_1.getOperand(1); // Const 767 if (Shl2_1.getOpcode() == ISD::Constant) { 768 int32_t ShlConst = 769 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue(); 770 int32_t Shl2Const = 771 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue(); 772 int32_t ValConst = 1 << (ShlConst+Shl2Const); 773 SDValue Val = CurDAG->getTargetConstant(-ValConst, dl, 774 MVT::i32); 775 if (ConstantSDNode *CN = 776 dyn_cast<ConstantSDNode>(Val.getNode())) 777 if (isInt<9>(CN->getSExtValue())) { 778 SDNode* Result = 779 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, MVT::i32, 780 Shl2_0, Val); 781 ReplaceNode(N, Result); 782 return; 783 } 784 } 785 } 786 } 787 } 788 } 789 } 790 } 791 SelectCode(N); 792 } 793 794 795 // 796 // If there is an zero_extend followed an intrinsic in DAG (this means - the 797 // result of the intrinsic is predicate); convert the zero_extend to 798 // transfer instruction. 799 // 800 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be 801 // converted into a MUX as predicate registers defined as 1 bit in the 802 // compiler. Architecture defines them as 8-bit registers. 803 // We want to preserve all the lower 8-bits and, not just 1 LSB bit. 804 // 805 void HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) { 806 SDLoc dl(N); 807 808 SDValue Op0 = N->getOperand(0); 809 EVT OpVT = Op0.getValueType(); 810 unsigned OpBW = OpVT.getSizeInBits(); 811 812 // Special handling for zero-extending a vector of booleans. 813 if (OpVT.isVector() && OpVT.getVectorElementType() == MVT::i1 && OpBW <= 64) { 814 SDNode *Mask = CurDAG->getMachineNode(Hexagon::C2_mask, dl, MVT::i64, Op0); 815 unsigned NE = OpVT.getVectorNumElements(); 816 EVT ExVT = N->getValueType(0); 817 unsigned ES = ExVT.getVectorElementType().getSizeInBits(); 818 uint64_t MV = 0, Bit = 1; 819 for (unsigned i = 0; i < NE; ++i) { 820 MV |= Bit; 821 Bit <<= ES; 822 } 823 SDValue Ones = CurDAG->getTargetConstant(MV, dl, MVT::i64); 824 SDNode *OnesReg = CurDAG->getMachineNode(Hexagon::CONST64_Int_Real, dl, 825 MVT::i64, Ones); 826 if (ExVT.getSizeInBits() == 32) { 827 SDNode *And = CurDAG->getMachineNode(Hexagon::A2_andp, dl, MVT::i64, 828 SDValue(Mask,0), SDValue(OnesReg,0)); 829 SDValue SubR = CurDAG->getTargetConstant(Hexagon::subreg_loreg, dl, 830 MVT::i32); 831 ReplaceNode(N, CurDAG->getMachineNode(Hexagon::EXTRACT_SUBREG, dl, ExVT, 832 SDValue(And, 0), SubR)); 833 return; 834 } 835 ReplaceNode(N, 836 CurDAG->getMachineNode(Hexagon::A2_andp, dl, ExVT, 837 SDValue(Mask, 0), SDValue(OnesReg, 0))); 838 return; 839 } 840 841 SDNode *IsIntrinsic = N->getOperand(0).getNode(); 842 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) { 843 unsigned ID = 844 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue(); 845 if (doesIntrinsicReturnPredicate(ID)) { 846 // Now we need to differentiate target data types. 847 if (N->getValueType(0) == MVT::i64) { 848 // Convert the zero_extend to Rs = Pd followed by A2_combinew(0,Rs). 849 SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32); 850 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl, 851 MVT::i32, 852 SDValue(IsIntrinsic, 0)); 853 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, 854 MVT::i32, 855 TargetConst0); 856 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl, 857 MVT::i64, MVT::Other, 858 SDValue(Result_2, 0), 859 SDValue(Result_1, 0)); 860 ReplaceNode(N, Result_3); 861 return; 862 } 863 if (N->getValueType(0) == MVT::i32) { 864 // Convert the zero_extend to Rs = Pd 865 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl, 866 MVT::i32, 867 SDValue(IsIntrinsic, 0)); 868 ReplaceNode(N, RsPd); 869 return; 870 } 871 llvm_unreachable("Unexpected value type"); 872 } 873 } 874 SelectCode(N); 875 } 876 877 878 // 879 // Handling intrinsics for circular load and bitreverse load. 880 // 881 void HexagonDAGToDAGISel::SelectIntrinsicWChain(SDNode *N) { 882 if (MachineSDNode *L = LoadInstrForLoadIntrinsic(N)) { 883 StoreInstrForLoadIntrinsic(L, N); 884 CurDAG->RemoveDeadNode(N); 885 return; 886 } 887 SelectCode(N); 888 } 889 890 void HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) { 891 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 892 unsigned Bits; 893 switch (IID) { 894 case Intrinsic::hexagon_S2_vsplatrb: 895 Bits = 8; 896 break; 897 case Intrinsic::hexagon_S2_vsplatrh: 898 Bits = 16; 899 break; 900 default: 901 SelectCode(N); 902 return; 903 } 904 905 SDValue V = N->getOperand(1); 906 SDValue U; 907 if (isValueExtension(V, Bits, U)) { 908 SDValue R = CurDAG->getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), 909 N->getOperand(0), U); 910 ReplaceNode(N, R.getNode()); 911 SelectCode(R.getNode()); 912 return; 913 } 914 SelectCode(N); 915 } 916 917 // 918 // Map floating point constant values. 919 // 920 void HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) { 921 SDLoc dl(N); 922 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N); 923 const APFloat &APF = CN->getValueAPF(); 924 if (N->getValueType(0) == MVT::f32) { 925 ReplaceNode( 926 N, CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32, 927 CurDAG->getTargetConstantFP( 928 APF.convertToFloat(), dl, MVT::f32))); 929 return; 930 } 931 else if (N->getValueType(0) == MVT::f64) { 932 ReplaceNode( 933 N, CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64, 934 CurDAG->getTargetConstantFP( 935 APF.convertToDouble(), dl, MVT::f64))); 936 return; 937 } 938 939 SelectCode(N); 940 } 941 942 // 943 // Map predicate true (encoded as -1 in LLVM) to a XOR. 944 // 945 void HexagonDAGToDAGISel::SelectConstant(SDNode *N) { 946 SDLoc dl(N); 947 if (N->getValueType(0) == MVT::i1) { 948 SDNode* Result = 0; 949 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 950 if (Val == -1) { 951 Result = CurDAG->getMachineNode(Hexagon::TFR_PdTrue, dl, MVT::i1); 952 } else if (Val == 0) { 953 Result = CurDAG->getMachineNode(Hexagon::TFR_PdFalse, dl, MVT::i1); 954 } 955 if (Result) { 956 ReplaceNode(N, Result); 957 return; 958 } 959 } 960 961 SelectCode(N); 962 } 963 964 965 // 966 // Map add followed by a asr -> asr +=. 967 // 968 void HexagonDAGToDAGISel::SelectAdd(SDNode *N) { 969 SDLoc dl(N); 970 if (N->getValueType(0) != MVT::i32) { 971 SelectCode(N); 972 return; 973 } 974 // Identify nodes of the form: add(asr(...)). 975 SDNode* Src1 = N->getOperand(0).getNode(); 976 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse() 977 || Src1->getValueType(0) != MVT::i32) { 978 SelectCode(N); 979 return; 980 } 981 982 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that 983 // Rd and Rd' are assigned to the same register 984 SDNode* Result = CurDAG->getMachineNode(Hexagon::S2_asr_r_r_acc, dl, MVT::i32, 985 N->getOperand(1), 986 Src1->getOperand(0), 987 Src1->getOperand(1)); 988 ReplaceNode(N, Result); 989 } 990 991 // 992 // Map the following, where possible. 993 // AND/FABS -> clrbit 994 // OR -> setbit 995 // XOR/FNEG ->toggle_bit. 996 // 997 void HexagonDAGToDAGISel::SelectBitOp(SDNode *N) { 998 SDLoc dl(N); 999 EVT ValueVT = N->getValueType(0); 1000 1001 // We handle only 32 and 64-bit bit ops. 1002 if (!(ValueVT == MVT::i32 || ValueVT == MVT::i64 || 1003 ValueVT == MVT::f32 || ValueVT == MVT::f64)) { 1004 SelectCode(N); 1005 return; 1006 } 1007 1008 // We handly only fabs and fneg for V5. 1009 unsigned Opc = N->getOpcode(); 1010 if ((Opc == ISD::FABS || Opc == ISD::FNEG) && !HST->hasV5TOps()) { 1011 SelectCode(N); 1012 return; 1013 } 1014 1015 int64_t Val = 0; 1016 if (Opc != ISD::FABS && Opc != ISD::FNEG) { 1017 if (N->getOperand(1).getOpcode() == ISD::Constant) 1018 Val = cast<ConstantSDNode>((N)->getOperand(1))->getSExtValue(); 1019 else { 1020 SelectCode(N); 1021 return; 1022 } 1023 } 1024 1025 if (Opc == ISD::AND) { 1026 // Check if this is a bit-clearing AND, if not select code the usual way. 1027 if ((ValueVT == MVT::i32 && isPowerOf2_32(~Val)) || 1028 (ValueVT == MVT::i64 && isPowerOf2_64(~Val))) 1029 Val = ~Val; 1030 else { 1031 SelectCode(N); 1032 return; 1033 } 1034 } 1035 1036 // If OR or AND is being fed by shl, srl and, sra don't do this change, 1037 // because Hexagon provide |= &= on shl, srl, and sra. 1038 // Traverse the DAG to see if there is shl, srl and sra. 1039 if (Opc == ISD::OR || Opc == ISD::AND) { 1040 switch (N->getOperand(0)->getOpcode()) { 1041 default: 1042 break; 1043 case ISD::SRA: 1044 case ISD::SRL: 1045 case ISD::SHL: 1046 SelectCode(N); 1047 return; 1048 } 1049 } 1050 1051 // Make sure it's power of 2. 1052 unsigned BitPos = 0; 1053 if (Opc != ISD::FABS && Opc != ISD::FNEG) { 1054 if ((ValueVT == MVT::i32 && !isPowerOf2_32(Val)) || 1055 (ValueVT == MVT::i64 && !isPowerOf2_64(Val))) { 1056 SelectCode(N); 1057 return; 1058 } 1059 1060 // Get the bit position. 1061 BitPos = countTrailingZeros(uint64_t(Val)); 1062 } else { 1063 // For fabs and fneg, it's always the 31st bit. 1064 BitPos = 31; 1065 } 1066 1067 unsigned BitOpc = 0; 1068 // Set the right opcode for bitwise operations. 1069 switch (Opc) { 1070 default: 1071 llvm_unreachable("Only bit-wise/abs/neg operations are allowed."); 1072 case ISD::AND: 1073 case ISD::FABS: 1074 BitOpc = Hexagon::S2_clrbit_i; 1075 break; 1076 case ISD::OR: 1077 BitOpc = Hexagon::S2_setbit_i; 1078 break; 1079 case ISD::XOR: 1080 case ISD::FNEG: 1081 BitOpc = Hexagon::S2_togglebit_i; 1082 break; 1083 } 1084 1085 SDNode *Result; 1086 // Get the right SDVal for the opcode. 1087 SDValue SDVal = CurDAG->getTargetConstant(BitPos, dl, MVT::i32); 1088 1089 if (ValueVT == MVT::i32 || ValueVT == MVT::f32) { 1090 Result = CurDAG->getMachineNode(BitOpc, dl, ValueVT, 1091 N->getOperand(0), SDVal); 1092 } else { 1093 // 64-bit gymnastic to use REG_SEQUENCE. But it's worth it. 1094 EVT SubValueVT; 1095 if (ValueVT == MVT::i64) 1096 SubValueVT = MVT::i32; 1097 else 1098 SubValueVT = MVT::f32; 1099 1100 SDNode *Reg = N->getOperand(0).getNode(); 1101 SDValue RegClass = CurDAG->getTargetConstant(Hexagon::DoubleRegsRegClassID, 1102 dl, MVT::i64); 1103 1104 SDValue SubregHiIdx = CurDAG->getTargetConstant(Hexagon::subreg_hireg, dl, 1105 MVT::i32); 1106 SDValue SubregLoIdx = CurDAG->getTargetConstant(Hexagon::subreg_loreg, dl, 1107 MVT::i32); 1108 1109 SDValue SubregHI = CurDAG->getTargetExtractSubreg(Hexagon::subreg_hireg, dl, 1110 MVT::i32, SDValue(Reg, 0)); 1111 1112 SDValue SubregLO = CurDAG->getTargetExtractSubreg(Hexagon::subreg_loreg, dl, 1113 MVT::i32, SDValue(Reg, 0)); 1114 1115 // Clear/set/toggle hi or lo registers depending on the bit position. 1116 if (SubValueVT != MVT::f32 && BitPos < 32) { 1117 SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT, 1118 SubregLO, SDVal); 1119 const SDValue Ops[] = { RegClass, SubregHI, SubregHiIdx, 1120 SDValue(Result0, 0), SubregLoIdx }; 1121 Result = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, 1122 dl, ValueVT, Ops); 1123 } else { 1124 if (Opc != ISD::FABS && Opc != ISD::FNEG) 1125 SDVal = CurDAG->getTargetConstant(BitPos-32, dl, MVT::i32); 1126 SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT, 1127 SubregHI, SDVal); 1128 const SDValue Ops[] = { RegClass, SDValue(Result0, 0), SubregHiIdx, 1129 SubregLO, SubregLoIdx }; 1130 Result = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, 1131 dl, ValueVT, Ops); 1132 } 1133 } 1134 1135 ReplaceNode(N, Result); 1136 } 1137 1138 1139 void HexagonDAGToDAGISel::SelectFrameIndex(SDNode *N) { 1140 MachineFrameInfo *MFI = MF->getFrameInfo(); 1141 const HexagonFrameLowering *HFI = HST->getFrameLowering(); 1142 int FX = cast<FrameIndexSDNode>(N)->getIndex(); 1143 unsigned StkA = HFI->getStackAlignment(); 1144 unsigned MaxA = MFI->getMaxAlignment(); 1145 SDValue FI = CurDAG->getTargetFrameIndex(FX, MVT::i32); 1146 SDLoc DL(N); 1147 SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32); 1148 SDNode *R = 0; 1149 1150 // Use TFR_FI when: 1151 // - the object is fixed, or 1152 // - there are no objects with higher-than-default alignment, or 1153 // - there are no dynamically allocated objects. 1154 // Otherwise, use TFR_FIA. 1155 if (FX < 0 || MaxA <= StkA || !MFI->hasVarSizedObjects()) { 1156 R = CurDAG->getMachineNode(Hexagon::TFR_FI, DL, MVT::i32, FI, Zero); 1157 } else { 1158 auto &HMFI = *MF->getInfo<HexagonMachineFunctionInfo>(); 1159 unsigned AR = HMFI.getStackAlignBaseVReg(); 1160 SDValue CH = CurDAG->getEntryNode(); 1161 SDValue Ops[] = { CurDAG->getCopyFromReg(CH, DL, AR, MVT::i32), FI, Zero }; 1162 R = CurDAG->getMachineNode(Hexagon::TFR_FIA, DL, MVT::i32, Ops); 1163 } 1164 1165 ReplaceNode(N, R); 1166 } 1167 1168 1169 void HexagonDAGToDAGISel::SelectBitcast(SDNode *N) { 1170 EVT SVT = N->getOperand(0).getValueType(); 1171 EVT DVT = N->getValueType(0); 1172 if (!SVT.isVector() || !DVT.isVector() || 1173 SVT.getVectorElementType() == MVT::i1 || 1174 DVT.getVectorElementType() == MVT::i1 || 1175 SVT.getSizeInBits() != DVT.getSizeInBits()) { 1176 SelectCode(N); 1177 return; 1178 } 1179 1180 CurDAG->ReplaceAllUsesOfValueWith(SDValue(N,0), N->getOperand(0)); 1181 CurDAG->RemoveDeadNode(N); 1182 } 1183 1184 1185 void HexagonDAGToDAGISel::Select(SDNode *N) { 1186 if (N->isMachineOpcode()) { 1187 N->setNodeId(-1); 1188 return; // Already selected. 1189 } 1190 1191 switch (N->getOpcode()) { 1192 case ISD::Constant: 1193 SelectConstant(N); 1194 return; 1195 1196 case ISD::ConstantFP: 1197 SelectConstantFP(N); 1198 return; 1199 1200 case ISD::FrameIndex: 1201 SelectFrameIndex(N); 1202 return; 1203 1204 case ISD::ADD: 1205 SelectAdd(N); 1206 return; 1207 1208 case ISD::BITCAST: 1209 SelectBitcast(N); 1210 return; 1211 1212 case ISD::SHL: 1213 SelectSHL(N); 1214 return; 1215 1216 case ISD::LOAD: 1217 SelectLoad(N); 1218 return; 1219 1220 case ISD::STORE: 1221 SelectStore(N); 1222 return; 1223 1224 case ISD::MUL: 1225 SelectMul(N); 1226 return; 1227 1228 case ISD::AND: 1229 case ISD::OR: 1230 case ISD::XOR: 1231 case ISD::FABS: 1232 case ISD::FNEG: 1233 SelectBitOp(N); 1234 return; 1235 1236 case ISD::ZERO_EXTEND: 1237 SelectZeroExtend(N); 1238 return; 1239 1240 case ISD::INTRINSIC_W_CHAIN: 1241 SelectIntrinsicWChain(N); 1242 return; 1243 1244 case ISD::INTRINSIC_WO_CHAIN: 1245 SelectIntrinsicWOChain(N); 1246 return; 1247 } 1248 1249 SelectCode(N); 1250 } 1251 1252 bool HexagonDAGToDAGISel:: 1253 SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 1254 std::vector<SDValue> &OutOps) { 1255 SDValue Inp = Op, Res; 1256 1257 switch (ConstraintID) { 1258 default: 1259 return true; 1260 case InlineAsm::Constraint_i: 1261 case InlineAsm::Constraint_o: // Offsetable. 1262 case InlineAsm::Constraint_v: // Not offsetable. 1263 case InlineAsm::Constraint_m: // Memory. 1264 if (SelectAddrFI(Inp, Res)) 1265 OutOps.push_back(Res); 1266 else 1267 OutOps.push_back(Inp); 1268 break; 1269 } 1270 1271 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); 1272 return false; 1273 } 1274 1275 1276 void HexagonDAGToDAGISel::PreprocessISelDAG() { 1277 SelectionDAG &DAG = *CurDAG; 1278 std::vector<SDNode*> Nodes; 1279 for (SDNode &Node : DAG.allnodes()) 1280 Nodes.push_back(&Node); 1281 1282 // Simplify: (or (select c x 0) z) -> (select c (or x z) z) 1283 // (or (select c 0 y) z) -> (select c z (or y z)) 1284 // This may not be the right thing for all targets, so do it here. 1285 for (auto I : Nodes) { 1286 if (I->getOpcode() != ISD::OR) 1287 continue; 1288 1289 auto IsZero = [] (const SDValue &V) -> bool { 1290 if (ConstantSDNode *SC = dyn_cast<ConstantSDNode>(V.getNode())) 1291 return SC->isNullValue(); 1292 return false; 1293 }; 1294 auto IsSelect0 = [IsZero] (const SDValue &Op) -> bool { 1295 if (Op.getOpcode() != ISD::SELECT) 1296 return false; 1297 return IsZero(Op.getOperand(1)) || IsZero(Op.getOperand(2)); 1298 }; 1299 1300 SDValue N0 = I->getOperand(0), N1 = I->getOperand(1); 1301 EVT VT = I->getValueType(0); 1302 bool SelN0 = IsSelect0(N0); 1303 SDValue SOp = SelN0 ? N0 : N1; 1304 SDValue VOp = SelN0 ? N1 : N0; 1305 1306 if (SOp.getOpcode() == ISD::SELECT && SOp.getNode()->hasOneUse()) { 1307 SDValue SC = SOp.getOperand(0); 1308 SDValue SX = SOp.getOperand(1); 1309 SDValue SY = SOp.getOperand(2); 1310 SDLoc DLS = SOp; 1311 if (IsZero(SY)) { 1312 SDValue NewOr = DAG.getNode(ISD::OR, DLS, VT, SX, VOp); 1313 SDValue NewSel = DAG.getNode(ISD::SELECT, DLS, VT, SC, NewOr, VOp); 1314 DAG.ReplaceAllUsesWith(I, NewSel.getNode()); 1315 } else if (IsZero(SX)) { 1316 SDValue NewOr = DAG.getNode(ISD::OR, DLS, VT, SY, VOp); 1317 SDValue NewSel = DAG.getNode(ISD::SELECT, DLS, VT, SC, VOp, NewOr); 1318 DAG.ReplaceAllUsesWith(I, NewSel.getNode()); 1319 } 1320 } 1321 } 1322 1323 // Transform: (store ch addr (add x (add (shl y c) e))) 1324 // to: (store ch addr (add x (shl (add y d) c))), 1325 // where e = (shl d c) for some integer d. 1326 // The purpose of this is to enable generation of loads/stores with 1327 // shifted addressing mode, i.e. mem(x+y<<#c). For that, the shift 1328 // value c must be 0, 1 or 2. 1329 for (auto I : Nodes) { 1330 if (I->getOpcode() != ISD::STORE) 1331 continue; 1332 1333 // I matched: (store ch addr Off) 1334 SDValue Off = I->getOperand(2); 1335 // Off needs to match: (add x (add (shl y c) (shl d c)))) 1336 if (Off.getOpcode() != ISD::ADD) 1337 continue; 1338 // Off matched: (add x T0) 1339 SDValue T0 = Off.getOperand(1); 1340 // T0 needs to match: (add T1 T2): 1341 if (T0.getOpcode() != ISD::ADD) 1342 continue; 1343 // T0 matched: (add T1 T2) 1344 SDValue T1 = T0.getOperand(0); 1345 SDValue T2 = T0.getOperand(1); 1346 // T1 needs to match: (shl y c) 1347 if (T1.getOpcode() != ISD::SHL) 1348 continue; 1349 SDValue C = T1.getOperand(1); 1350 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(C.getNode()); 1351 if (CN == nullptr) 1352 continue; 1353 unsigned CV = CN->getZExtValue(); 1354 if (CV > 2) 1355 continue; 1356 // T2 needs to match e, where e = (shl d c) for some d. 1357 ConstantSDNode *EN = dyn_cast<ConstantSDNode>(T2.getNode()); 1358 if (EN == nullptr) 1359 continue; 1360 unsigned EV = EN->getZExtValue(); 1361 if (EV % (1 << CV) != 0) 1362 continue; 1363 unsigned DV = EV / (1 << CV); 1364 1365 // Replace T0 with: (shl (add y d) c) 1366 SDLoc DL = SDLoc(I); 1367 EVT VT = T0.getValueType(); 1368 SDValue D = DAG.getConstant(DV, DL, VT); 1369 // NewAdd = (add y d) 1370 SDValue NewAdd = DAG.getNode(ISD::ADD, DL, VT, T1.getOperand(0), D); 1371 // NewShl = (shl NewAdd c) 1372 SDValue NewShl = DAG.getNode(ISD::SHL, DL, VT, NewAdd, C); 1373 ReplaceNode(T0.getNode(), NewShl.getNode()); 1374 } 1375 } 1376 1377 void HexagonDAGToDAGISel::EmitFunctionEntryCode() { 1378 auto &HST = static_cast<const HexagonSubtarget&>(MF->getSubtarget()); 1379 auto &HFI = *HST.getFrameLowering(); 1380 if (!HFI.needsAligna(*MF)) 1381 return; 1382 1383 MachineFrameInfo *MFI = MF->getFrameInfo(); 1384 MachineBasicBlock *EntryBB = &MF->front(); 1385 unsigned AR = FuncInfo->CreateReg(MVT::i32); 1386 unsigned MaxA = MFI->getMaxAlignment(); 1387 BuildMI(EntryBB, DebugLoc(), HII->get(Hexagon::ALIGNA), AR) 1388 .addImm(MaxA); 1389 MF->getInfo<HexagonMachineFunctionInfo>()->setStackAlignBaseVReg(AR); 1390 } 1391 1392 // Match a frame index that can be used in an addressing mode. 1393 bool HexagonDAGToDAGISel::SelectAddrFI(SDValue& N, SDValue &R) { 1394 if (N.getOpcode() != ISD::FrameIndex) 1395 return false; 1396 auto &HFI = *HST->getFrameLowering(); 1397 MachineFrameInfo *MFI = MF->getFrameInfo(); 1398 int FX = cast<FrameIndexSDNode>(N)->getIndex(); 1399 if (!MFI->isFixedObjectIndex(FX) && HFI.needsAligna(*MF)) 1400 return false; 1401 R = CurDAG->getTargetFrameIndex(FX, MVT::i32); 1402 return true; 1403 } 1404 1405 inline bool HexagonDAGToDAGISel::SelectAddrGA(SDValue &N, SDValue &R) { 1406 return SelectGlobalAddress(N, R, false); 1407 } 1408 1409 inline bool HexagonDAGToDAGISel::SelectAddrGP(SDValue &N, SDValue &R) { 1410 return SelectGlobalAddress(N, R, true); 1411 } 1412 1413 bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R, 1414 bool UseGP) { 1415 switch (N.getOpcode()) { 1416 case ISD::ADD: { 1417 SDValue N0 = N.getOperand(0); 1418 SDValue N1 = N.getOperand(1); 1419 unsigned GAOpc = N0.getOpcode(); 1420 if (UseGP && GAOpc != HexagonISD::CONST32_GP) 1421 return false; 1422 if (!UseGP && GAOpc != HexagonISD::CONST32) 1423 return false; 1424 if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1)) { 1425 SDValue Addr = N0.getOperand(0); 1426 if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Addr)) { 1427 if (GA->getOpcode() == ISD::TargetGlobalAddress) { 1428 uint64_t NewOff = GA->getOffset() + (uint64_t)Const->getSExtValue(); 1429 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(Const), 1430 N.getValueType(), NewOff); 1431 return true; 1432 } 1433 } 1434 } 1435 break; 1436 } 1437 case HexagonISD::CONST32: 1438 // The operand(0) of CONST32 is TargetGlobalAddress, which is what we 1439 // want in the instruction. 1440 if (!UseGP) 1441 R = N.getOperand(0); 1442 return !UseGP; 1443 case HexagonISD::CONST32_GP: 1444 if (UseGP) 1445 R = N.getOperand(0); 1446 return UseGP; 1447 default: 1448 return false; 1449 } 1450 1451 return false; 1452 } 1453 1454 bool HexagonDAGToDAGISel::isValueExtension(const SDValue &Val, 1455 unsigned FromBits, SDValue &Src) { 1456 unsigned Opc = Val.getOpcode(); 1457 switch (Opc) { 1458 case ISD::SIGN_EXTEND: 1459 case ISD::ZERO_EXTEND: 1460 case ISD::ANY_EXTEND: { 1461 SDValue const &Op0 = Val.getOperand(0); 1462 EVT T = Op0.getValueType(); 1463 if (T.isInteger() && T.getSizeInBits() == FromBits) { 1464 Src = Op0; 1465 return true; 1466 } 1467 break; 1468 } 1469 case ISD::SIGN_EXTEND_INREG: 1470 case ISD::AssertSext: 1471 case ISD::AssertZext: 1472 if (Val.getOperand(0).getValueType().isInteger()) { 1473 VTSDNode *T = cast<VTSDNode>(Val.getOperand(1)); 1474 if (T->getVT().getSizeInBits() == FromBits) { 1475 Src = Val.getOperand(0); 1476 return true; 1477 } 1478 } 1479 break; 1480 case ISD::AND: { 1481 // Check if this is an AND with "FromBits" of lower bits set to 1. 1482 uint64_t FromMask = (1 << FromBits) - 1; 1483 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) { 1484 if (C->getZExtValue() == FromMask) { 1485 Src = Val.getOperand(1); 1486 return true; 1487 } 1488 } 1489 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) { 1490 if (C->getZExtValue() == FromMask) { 1491 Src = Val.getOperand(0); 1492 return true; 1493 } 1494 } 1495 break; 1496 } 1497 case ISD::OR: 1498 case ISD::XOR: { 1499 // OR/XOR with the lower "FromBits" bits set to 0. 1500 uint64_t FromMask = (1 << FromBits) - 1; 1501 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) { 1502 if ((C->getZExtValue() & FromMask) == 0) { 1503 Src = Val.getOperand(1); 1504 return true; 1505 } 1506 } 1507 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) { 1508 if ((C->getZExtValue() & FromMask) == 0) { 1509 Src = Val.getOperand(0); 1510 return true; 1511 } 1512 } 1513 } 1514 default: 1515 break; 1516 } 1517 return false; 1518 } 1519 1520 bool HexagonDAGToDAGISel::isAlignedMemNode(const MemSDNode *N) const { 1521 return N->getAlignment() >= N->getMemoryVT().getStoreSize(); 1522 } 1523