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 #define DEBUG_TYPE "hexagon-isel" 15 #include "Hexagon.h" 16 #include "HexagonISelLowering.h" 17 #include "HexagonTargetMachine.h" 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/IR/Intrinsics.h" 20 #include "llvm/CodeGen/SelectionDAGISel.h" 21 #include "llvm/Support/CommandLine.h" 22 #include "llvm/Support/Compiler.h" 23 #include "llvm/Support/Debug.h" 24 using namespace llvm; 25 26 static 27 cl::opt<unsigned> 28 MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders", 29 cl::Hidden, cl::init(2), 30 cl::desc("Maximum number of uses of a global address such that we still us a" 31 "constant extended instruction")); 32 33 //===----------------------------------------------------------------------===// 34 // Instruction Selector Implementation 35 //===----------------------------------------------------------------------===// 36 37 namespace llvm { 38 void initializeHexagonDAGToDAGISelPass(PassRegistry&); 39 } 40 41 //===--------------------------------------------------------------------===// 42 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine 43 /// instructions for SelectionDAG operations. 44 /// 45 namespace { 46 class HexagonDAGToDAGISel : public SelectionDAGISel { 47 /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can 48 /// make the right decision when generating code for different targets. 49 const HexagonSubtarget &Subtarget; 50 51 // Keep a reference to HexagonTargetMachine. 52 HexagonTargetMachine& TM; 53 const HexagonInstrInfo *TII; 54 DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap; 55 public: 56 explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine, 57 CodeGenOpt::Level OptLevel) 58 : SelectionDAGISel(targetmachine, OptLevel), 59 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()), 60 TM(targetmachine), 61 TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) { 62 initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry()); 63 } 64 bool hasNumUsesBelowThresGA(SDNode *N) const; 65 66 SDNode *Select(SDNode *N); 67 68 // Complex Pattern Selectors. 69 inline bool foldGlobalAddress(SDValue &N, SDValue &R); 70 inline bool foldGlobalAddressGP(SDValue &N, SDValue &R); 71 bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP); 72 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2); 73 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2); 74 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2); 75 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2); 76 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset); 77 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2); 78 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset); 79 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2); 80 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2); 81 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2); 82 83 virtual const char *getPassName() const { 84 return "Hexagon DAG->DAG Pattern Instruction Selection"; 85 } 86 87 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 88 /// inline asm expressions. 89 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 90 char ConstraintCode, 91 std::vector<SDValue> &OutOps); 92 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset); 93 94 SDNode *SelectLoad(SDNode *N); 95 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl); 96 SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl); 97 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode, 98 DebugLoc dl); 99 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode, 100 DebugLoc dl); 101 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl); 102 SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl); 103 SDNode *SelectStore(SDNode *N); 104 SDNode *SelectSHL(SDNode *N); 105 SDNode *SelectSelect(SDNode *N); 106 SDNode *SelectTruncate(SDNode *N); 107 SDNode *SelectMul(SDNode *N); 108 SDNode *SelectZeroExtend(SDNode *N); 109 SDNode *SelectIntrinsicWOChain(SDNode *N); 110 SDNode *SelectIntrinsicWChain(SDNode *N); 111 SDNode *SelectConstant(SDNode *N); 112 SDNode *SelectConstantFP(SDNode *N); 113 SDNode *SelectAdd(SDNode *N); 114 bool isConstExtProfitable(SDNode *N) const; 115 116 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range 117 // [1..128], used in cmpb.gtu instructions. 118 inline SDValue XformU7ToU7M1Imm(signed Imm) { 119 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op"); 120 return CurDAG->getTargetConstant(Imm - 1, MVT::i8); 121 } 122 123 // Include the pieces autogenerated from the target description. 124 #include "HexagonGenDAGISel.inc" 125 }; 126 } // end anonymous namespace 127 128 129 /// createHexagonISelDag - This pass converts a legalized DAG into a 130 /// Hexagon-specific DAG, ready for instruction scheduling. 131 /// 132 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM, 133 CodeGenOpt::Level OptLevel) { 134 return new HexagonDAGToDAGISel(TM, OptLevel); 135 } 136 137 static void initializePassOnce(PassRegistry &Registry) { 138 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection"; 139 PassInfo *PI = new PassInfo(Name, "hexagon-isel", 140 &SelectionDAGISel::ID, 0, false, false); 141 Registry.registerPass(*PI, true); 142 } 143 144 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) { 145 CALL_ONCE_INITIALIZATION(initializePassOnce) 146 } 147 148 149 static bool IsS11_0_Offset(SDNode * S) { 150 ConstantSDNode *N = cast<ConstantSDNode>(S); 151 152 // immS16 predicate - True if the immediate fits in a 16-bit sign extended 153 // field. 154 int64_t v = (int64_t)N->getSExtValue(); 155 return isInt<11>(v); 156 } 157 158 159 static bool IsS11_1_Offset(SDNode * S) { 160 ConstantSDNode *N = cast<ConstantSDNode>(S); 161 162 // immS16 predicate - True if the immediate fits in a 16-bit sign extended 163 // field. 164 int64_t v = (int64_t)N->getSExtValue(); 165 return isShiftedInt<11,1>(v); 166 } 167 168 169 static bool IsS11_2_Offset(SDNode * S) { 170 ConstantSDNode *N = cast<ConstantSDNode>(S); 171 172 // immS16 predicate - True if the immediate fits in a 16-bit sign extended 173 // field. 174 int64_t v = (int64_t)N->getSExtValue(); 175 return isShiftedInt<11,2>(v); 176 } 177 178 179 static bool IsS11_3_Offset(SDNode * S) { 180 ConstantSDNode *N = cast<ConstantSDNode>(S); 181 182 // immS16 predicate - True if the immediate fits in a 16-bit sign extended 183 // field. 184 int64_t v = (int64_t)N->getSExtValue(); 185 return isShiftedInt<11,3>(v); 186 } 187 188 189 static bool IsU6_0_Offset(SDNode * S) { 190 ConstantSDNode *N = cast<ConstantSDNode>(S); 191 192 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended 193 // field. 194 int64_t v = (int64_t)N->getSExtValue(); 195 return isUInt<6>(v); 196 } 197 198 199 static bool IsU6_1_Offset(SDNode * S) { 200 ConstantSDNode *N = cast<ConstantSDNode>(S); 201 202 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended 203 // field. 204 int64_t v = (int64_t)N->getSExtValue(); 205 return isShiftedUInt<6,1>(v); 206 } 207 208 209 static bool IsU6_2_Offset(SDNode * S) { 210 ConstantSDNode *N = cast<ConstantSDNode>(S); 211 212 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended 213 // field. 214 int64_t v = (int64_t)N->getSExtValue(); 215 return isShiftedUInt<6,2>(v); 216 } 217 218 219 // Intrinsics that return a a predicate. 220 static unsigned doesIntrinsicReturnPredicate(unsigned ID) 221 { 222 switch (ID) { 223 default: 224 return 0; 225 case Intrinsic::hexagon_C2_cmpeq: 226 case Intrinsic::hexagon_C2_cmpgt: 227 case Intrinsic::hexagon_C2_cmpgtu: 228 case Intrinsic::hexagon_C2_cmpgtup: 229 case Intrinsic::hexagon_C2_cmpgtp: 230 case Intrinsic::hexagon_C2_cmpeqp: 231 case Intrinsic::hexagon_C2_bitsset: 232 case Intrinsic::hexagon_C2_bitsclr: 233 case Intrinsic::hexagon_C2_cmpeqi: 234 case Intrinsic::hexagon_C2_cmpgti: 235 case Intrinsic::hexagon_C2_cmpgtui: 236 case Intrinsic::hexagon_C2_cmpgei: 237 case Intrinsic::hexagon_C2_cmpgeui: 238 case Intrinsic::hexagon_C2_cmplt: 239 case Intrinsic::hexagon_C2_cmpltu: 240 case Intrinsic::hexagon_C2_bitsclri: 241 case Intrinsic::hexagon_C2_and: 242 case Intrinsic::hexagon_C2_or: 243 case Intrinsic::hexagon_C2_xor: 244 case Intrinsic::hexagon_C2_andn: 245 case Intrinsic::hexagon_C2_not: 246 case Intrinsic::hexagon_C2_orn: 247 case Intrinsic::hexagon_C2_pxfer_map: 248 case Intrinsic::hexagon_C2_any8: 249 case Intrinsic::hexagon_C2_all8: 250 case Intrinsic::hexagon_A2_vcmpbeq: 251 case Intrinsic::hexagon_A2_vcmpbgtu: 252 case Intrinsic::hexagon_A2_vcmpheq: 253 case Intrinsic::hexagon_A2_vcmphgt: 254 case Intrinsic::hexagon_A2_vcmphgtu: 255 case Intrinsic::hexagon_A2_vcmpweq: 256 case Intrinsic::hexagon_A2_vcmpwgt: 257 case Intrinsic::hexagon_A2_vcmpwgtu: 258 case Intrinsic::hexagon_C2_tfrrp: 259 case Intrinsic::hexagon_S2_tstbit_i: 260 case Intrinsic::hexagon_S2_tstbit_r: 261 return 1; 262 } 263 } 264 265 266 // Intrinsics that have predicate operands. 267 static unsigned doesIntrinsicContainPredicate(unsigned ID) 268 { 269 switch (ID) { 270 default: 271 return 0; 272 case Intrinsic::hexagon_C2_tfrpr: 273 return Hexagon::TFR_RsPd; 274 case Intrinsic::hexagon_C2_and: 275 return Hexagon::AND_pp; 276 case Intrinsic::hexagon_C2_xor: 277 return Hexagon::XOR_pp; 278 case Intrinsic::hexagon_C2_or: 279 return Hexagon::OR_pp; 280 case Intrinsic::hexagon_C2_not: 281 return Hexagon::NOT_p; 282 case Intrinsic::hexagon_C2_any8: 283 return Hexagon::ANY_pp; 284 case Intrinsic::hexagon_C2_all8: 285 return Hexagon::ALL_pp; 286 case Intrinsic::hexagon_C2_vitpack: 287 return Hexagon::VITPACK_pp; 288 case Intrinsic::hexagon_C2_mask: 289 return Hexagon::MASK_p; 290 case Intrinsic::hexagon_C2_mux: 291 return Hexagon::MUX_rr; 292 293 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but 294 // that's how it's mapped in q6protos.h. 295 case Intrinsic::hexagon_C2_muxir: 296 return Hexagon::MUX_ri; 297 298 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but 299 // that's how it's mapped in q6protos.h. 300 case Intrinsic::hexagon_C2_muxri: 301 return Hexagon::MUX_ir; 302 303 case Intrinsic::hexagon_C2_muxii: 304 return Hexagon::MUX_ii; 305 case Intrinsic::hexagon_C2_vmux: 306 return Hexagon::VMUX_prr64; 307 case Intrinsic::hexagon_S2_valignrb: 308 return Hexagon::VALIGN_rrp; 309 case Intrinsic::hexagon_S2_vsplicerb: 310 return Hexagon::VSPLICE_rrp; 311 } 312 } 313 314 315 static bool OffsetFitsS11(EVT MemType, int64_t Offset) { 316 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) { 317 return true; 318 } 319 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) { 320 return true; 321 } 322 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) { 323 return true; 324 } 325 if (MemType == MVT::i8 && isInt<11>(Offset)) { 326 return true; 327 } 328 return false; 329 } 330 331 332 // 333 // Try to lower loads of GlobalAdresses into base+offset loads. Custom 334 // lowering for GlobalAddress nodes has already turned it into a 335 // CONST32. 336 // 337 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) { 338 SDValue Chain = LD->getChain(); 339 SDNode* Const32 = LD->getBasePtr().getNode(); 340 unsigned Opcode = 0; 341 342 if (Const32->getOpcode() == HexagonISD::CONST32 && 343 ISD::isNormalLoad(LD)) { 344 SDValue Base = Const32->getOperand(0); 345 EVT LoadedVT = LD->getMemoryVT(); 346 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset(); 347 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) { 348 MVT PointerTy = TLI.getPointerTy(); 349 const GlobalValue* GV = 350 cast<GlobalAddressSDNode>(Base)->getGlobal(); 351 SDValue TargAddr = 352 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0); 353 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set, 354 dl, PointerTy, 355 TargAddr); 356 // Figure out base + offset opcode 357 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed; 358 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed; 359 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed; 360 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed; 361 else llvm_unreachable("unknown memory type"); 362 363 // Build indexed load. 364 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy); 365 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, 366 LD->getValueType(0), 367 MVT::Other, 368 SDValue(NewBase,0), 369 TargetConstOff, 370 Chain); 371 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 372 MemOp[0] = LD->getMemOperand(); 373 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 374 ReplaceUses(LD, Result); 375 return Result; 376 } 377 } 378 379 return SelectCode(LD); 380 } 381 382 383 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD, 384 unsigned Opcode, 385 DebugLoc dl) 386 { 387 SDValue Chain = LD->getChain(); 388 EVT LoadedVT = LD->getMemoryVT(); 389 SDValue Base = LD->getBasePtr(); 390 SDValue Offset = LD->getOffset(); 391 SDNode *OffsetNode = Offset.getNode(); 392 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 393 SDValue N1 = LD->getOperand(1); 394 SDValue CPTmpN1_0; 395 SDValue CPTmpN1_1; 396 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) && 397 N1.getNode()->getValueType(0) == MVT::i32) { 398 if (TII->isValidAutoIncImm(LoadedVT, Val)) { 399 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32); 400 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32, 401 MVT::Other, Base, TargetConst, 402 Chain); 403 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64, 404 SDValue(Result_1, 0)); 405 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 406 MemOp[0] = LD->getMemOperand(); 407 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 408 const SDValue Froms[] = { SDValue(LD, 0), 409 SDValue(LD, 1), 410 SDValue(LD, 2) 411 }; 412 const SDValue Tos[] = { SDValue(Result_2, 0), 413 SDValue(Result_1, 1), 414 SDValue(Result_1, 2) 415 }; 416 ReplaceUses(Froms, Tos, 3); 417 return Result_2; 418 } 419 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 420 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 421 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 422 MVT::Other, Base, TargetConst0, 423 Chain); 424 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, 425 MVT::i64, SDValue(Result_1, 0)); 426 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, 427 MVT::i32, Base, TargetConstVal, 428 SDValue(Result_1, 1)); 429 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 430 MemOp[0] = LD->getMemOperand(); 431 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 432 const SDValue Froms[] = { SDValue(LD, 0), 433 SDValue(LD, 1), 434 SDValue(LD, 2) 435 }; 436 const SDValue Tos[] = { SDValue(Result_2, 0), 437 SDValue(Result_3, 0), 438 SDValue(Result_1, 1) 439 }; 440 ReplaceUses(Froms, Tos, 3); 441 return Result_2; 442 } 443 return SelectCode(LD); 444 } 445 446 447 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD, 448 unsigned Opcode, 449 DebugLoc dl) 450 { 451 SDValue Chain = LD->getChain(); 452 EVT LoadedVT = LD->getMemoryVT(); 453 SDValue Base = LD->getBasePtr(); 454 SDValue Offset = LD->getOffset(); 455 SDNode *OffsetNode = Offset.getNode(); 456 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 457 SDValue N1 = LD->getOperand(1); 458 SDValue CPTmpN1_0; 459 SDValue CPTmpN1_1; 460 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) && 461 N1.getNode()->getValueType(0) == MVT::i32) { 462 if (TII->isValidAutoIncImm(LoadedVT, Val)) { 463 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 464 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 465 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 466 MVT::i32, MVT::Other, Base, 467 TargetConstVal, Chain); 468 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32, 469 TargetConst0); 470 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl, 471 MVT::i64, MVT::Other, 472 SDValue(Result_2,0), 473 SDValue(Result_1,0)); 474 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 475 MemOp[0] = LD->getMemOperand(); 476 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 477 const SDValue Froms[] = { SDValue(LD, 0), 478 SDValue(LD, 1), 479 SDValue(LD, 2) 480 }; 481 const SDValue Tos[] = { SDValue(Result_3, 0), 482 SDValue(Result_1, 1), 483 SDValue(Result_1, 2) 484 }; 485 ReplaceUses(Froms, Tos, 3); 486 return Result_3; 487 } 488 489 // Generate an indirect load. 490 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 491 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 492 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 493 MVT::Other, 494 Base, TargetConst0, Chain); 495 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32, 496 TargetConst0); 497 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl, 498 MVT::i64, MVT::Other, 499 SDValue(Result_2,0), 500 SDValue(Result_1,0)); 501 // Add offset to base. 502 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32, 503 Base, TargetConstVal, 504 SDValue(Result_1, 1)); 505 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 506 MemOp[0] = LD->getMemOperand(); 507 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 508 const SDValue Froms[] = { SDValue(LD, 0), 509 SDValue(LD, 1), 510 SDValue(LD, 2) 511 }; 512 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value. 513 SDValue(Result_4, 0), // New address. 514 SDValue(Result_1, 1) 515 }; 516 ReplaceUses(Froms, Tos, 3); 517 return Result_3; 518 } 519 520 return SelectCode(LD); 521 } 522 523 524 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) { 525 SDValue Chain = LD->getChain(); 526 SDValue Base = LD->getBasePtr(); 527 SDValue Offset = LD->getOffset(); 528 SDNode *OffsetNode = Offset.getNode(); 529 // Get the constant value. 530 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 531 EVT LoadedVT = LD->getMemoryVT(); 532 unsigned Opcode = 0; 533 534 // Check for zero ext loads. 535 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD); 536 537 // Figure out the opcode. 538 if (LoadedVT == MVT::i64) { 539 if (TII->isValidAutoIncImm(LoadedVT, Val)) 540 Opcode = Hexagon::POST_LDrid; 541 else 542 Opcode = Hexagon::LDrid; 543 } else if (LoadedVT == MVT::i32) { 544 if (TII->isValidAutoIncImm(LoadedVT, Val)) 545 Opcode = Hexagon::POST_LDriw; 546 else 547 Opcode = Hexagon::LDriw; 548 } else if (LoadedVT == MVT::i16) { 549 if (TII->isValidAutoIncImm(LoadedVT, Val)) 550 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih; 551 else 552 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih; 553 } else if (LoadedVT == MVT::i8) { 554 if (TII->isValidAutoIncImm(LoadedVT, Val)) 555 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib; 556 else 557 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib; 558 } else 559 llvm_unreachable("unknown memory type"); 560 561 // For zero ext i64 loads, we need to add combine instructions. 562 if (LD->getValueType(0) == MVT::i64 && 563 LD->getExtensionType() == ISD::ZEXTLOAD) { 564 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl); 565 } 566 if (LD->getValueType(0) == MVT::i64 && 567 LD->getExtensionType() == ISD::SEXTLOAD) { 568 // Handle sign ext i64 loads. 569 return SelectIndexedLoadSignExtend64(LD, Opcode, dl); 570 } 571 if (TII->isValidAutoIncImm(LoadedVT, Val)) { 572 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 573 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, 574 LD->getValueType(0), 575 MVT::i32, MVT::Other, Base, 576 TargetConstVal, Chain); 577 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 578 MemOp[0] = LD->getMemOperand(); 579 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 580 const SDValue Froms[] = { SDValue(LD, 0), 581 SDValue(LD, 1), 582 SDValue(LD, 2) 583 }; 584 const SDValue Tos[] = { SDValue(Result, 0), 585 SDValue(Result, 1), 586 SDValue(Result, 2) 587 }; 588 ReplaceUses(Froms, Tos, 3); 589 return Result; 590 } else { 591 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 592 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 593 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, 594 LD->getValueType(0), 595 MVT::Other, Base, TargetConst0, 596 Chain); 597 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32, 598 Base, TargetConstVal, 599 SDValue(Result_1, 1)); 600 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 601 MemOp[0] = LD->getMemOperand(); 602 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 603 const SDValue Froms[] = { SDValue(LD, 0), 604 SDValue(LD, 1), 605 SDValue(LD, 2) 606 }; 607 const SDValue Tos[] = { SDValue(Result_1, 0), 608 SDValue(Result_2, 0), 609 SDValue(Result_1, 1) 610 }; 611 ReplaceUses(Froms, Tos, 3); 612 return Result_1; 613 } 614 } 615 616 617 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) { 618 SDNode *result; 619 DebugLoc dl = N->getDebugLoc(); 620 LoadSDNode *LD = cast<LoadSDNode>(N); 621 ISD::MemIndexedMode AM = LD->getAddressingMode(); 622 623 // Handle indexed loads. 624 if (AM != ISD::UNINDEXED) { 625 result = SelectIndexedLoad(LD, dl); 626 } else { 627 result = SelectBaseOffsetLoad(LD, dl); 628 } 629 630 return result; 631 } 632 633 634 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) { 635 SDValue Chain = ST->getChain(); 636 SDValue Base = ST->getBasePtr(); 637 SDValue Offset = ST->getOffset(); 638 SDValue Value = ST->getValue(); 639 SDNode *OffsetNode = Offset.getNode(); 640 // Get the constant value. 641 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 642 EVT StoredVT = ST->getMemoryVT(); 643 644 // Offset value must be within representable range 645 // and must have correct alignment properties. 646 if (TII->isValidAutoIncImm(StoredVT, Val)) { 647 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value, 648 Chain}; 649 unsigned Opcode = 0; 650 651 // Figure out the post inc version of opcode. 652 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri; 653 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri; 654 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri; 655 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri; 656 else llvm_unreachable("unknown memory type"); 657 658 // Build post increment store. 659 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 660 MVT::Other, Ops, 4); 661 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 662 MemOp[0] = ST->getMemOperand(); 663 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 664 665 ReplaceUses(ST, Result); 666 ReplaceUses(SDValue(ST,1), SDValue(Result,1)); 667 return Result; 668 } 669 670 // Note: Order of operands matches the def of instruction: 671 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ... 672 // and it differs for POST_ST* for instance. 673 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value, 674 Chain}; 675 unsigned Opcode = 0; 676 677 // Figure out the opcode. 678 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid; 679 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed; 680 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih; 681 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib; 682 else llvm_unreachable("unknown memory type"); 683 684 // Build regular store. 685 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 686 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops, 687 4); 688 // Build splitted incriment instruction. 689 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32, 690 Base, 691 TargetConstVal, 692 SDValue(Result_1, 0)); 693 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 694 MemOp[0] = ST->getMemOperand(); 695 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 696 697 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0)); 698 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0)); 699 return Result_2; 700 } 701 702 703 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST, 704 DebugLoc dl) { 705 SDValue Chain = ST->getChain(); 706 SDNode* Const32 = ST->getBasePtr().getNode(); 707 SDValue Value = ST->getValue(); 708 unsigned Opcode = 0; 709 710 // Try to lower stores of GlobalAdresses into indexed stores. Custom 711 // lowering for GlobalAddress nodes has already turned it into a 712 // CONST32. Avoid truncating stores for the moment. Post-inc stores 713 // do the same. Don't think there's a reason for it, so will file a 714 // bug to fix. 715 if ((Const32->getOpcode() == HexagonISD::CONST32) && 716 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) { 717 SDValue Base = Const32->getOperand(0); 718 if (Base.getOpcode() == ISD::TargetGlobalAddress) { 719 EVT StoredVT = ST->getMemoryVT(); 720 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset(); 721 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) { 722 MVT PointerTy = TLI.getPointerTy(); 723 const GlobalValue* GV = 724 cast<GlobalAddressSDNode>(Base)->getGlobal(); 725 SDValue TargAddr = 726 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0); 727 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set, 728 dl, PointerTy, 729 TargAddr); 730 731 // Figure out base + offset opcode 732 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed; 733 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed; 734 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed; 735 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed; 736 else llvm_unreachable("unknown memory type"); 737 738 SDValue Ops[] = {SDValue(NewBase,0), 739 CurDAG->getTargetConstant(Offset,PointerTy), 740 Value, Chain}; 741 // build indexed store 742 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, 743 MVT::Other, Ops, 4); 744 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 745 MemOp[0] = ST->getMemOperand(); 746 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 747 ReplaceUses(ST, Result); 748 return Result; 749 } 750 } 751 } 752 753 return SelectCode(ST); 754 } 755 756 757 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) { 758 DebugLoc dl = N->getDebugLoc(); 759 StoreSDNode *ST = cast<StoreSDNode>(N); 760 ISD::MemIndexedMode AM = ST->getAddressingMode(); 761 762 // Handle indexed stores. 763 if (AM != ISD::UNINDEXED) { 764 return SelectIndexedStore(ST, dl); 765 } 766 767 return SelectBaseOffsetStore(ST, dl); 768 } 769 770 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) { 771 DebugLoc dl = N->getDebugLoc(); 772 773 // 774 // %conv.i = sext i32 %tmp1 to i64 775 // %conv2.i = sext i32 %add to i64 776 // %mul.i = mul nsw i64 %conv2.i, %conv.i 777 // 778 // --- match with the following --- 779 // 780 // %mul.i = mpy (%tmp1, %add) 781 // 782 783 if (N->getValueType(0) == MVT::i64) { 784 // Shifting a i64 signed multiply. 785 SDValue MulOp0 = N->getOperand(0); 786 SDValue MulOp1 = N->getOperand(1); 787 788 SDValue OP0; 789 SDValue OP1; 790 791 // Handle sign_extend and sextload. 792 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) { 793 SDValue Sext0 = MulOp0.getOperand(0); 794 if (Sext0.getNode()->getValueType(0) != MVT::i32) { 795 return SelectCode(N); 796 } 797 798 OP0 = Sext0; 799 } else if (MulOp0.getOpcode() == ISD::LOAD) { 800 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode()); 801 if (LD->getMemoryVT() != MVT::i32 || 802 LD->getExtensionType() != ISD::SEXTLOAD || 803 LD->getAddressingMode() != ISD::UNINDEXED) { 804 return SelectCode(N); 805 } 806 807 SDValue Chain = LD->getChain(); 808 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 809 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 810 MVT::Other, 811 LD->getBasePtr(), TargetConst0, 812 Chain), 0); 813 } else { 814 return SelectCode(N); 815 } 816 817 // Same goes for the second operand. 818 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) { 819 SDValue Sext1 = MulOp1.getOperand(0); 820 if (Sext1.getNode()->getValueType(0) != MVT::i32) { 821 return SelectCode(N); 822 } 823 824 OP1 = Sext1; 825 } else if (MulOp1.getOpcode() == ISD::LOAD) { 826 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode()); 827 if (LD->getMemoryVT() != MVT::i32 || 828 LD->getExtensionType() != ISD::SEXTLOAD || 829 LD->getAddressingMode() != ISD::UNINDEXED) { 830 return SelectCode(N); 831 } 832 833 SDValue Chain = LD->getChain(); 834 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 835 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 836 MVT::Other, 837 LD->getBasePtr(), TargetConst0, 838 Chain), 0); 839 } else { 840 return SelectCode(N); 841 } 842 843 // Generate a mpy instruction. 844 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64, 845 OP0, OP1); 846 ReplaceUses(N, Result); 847 return Result; 848 } 849 850 return SelectCode(N); 851 } 852 853 854 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) { 855 DebugLoc dl = N->getDebugLoc(); 856 SDValue N0 = N->getOperand(0); 857 if (N0.getOpcode() == ISD::SETCC) { 858 SDValue N00 = N0.getOperand(0); 859 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) { 860 SDValue N000 = N00.getOperand(0); 861 SDValue N001 = N00.getOperand(1); 862 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) { 863 SDValue N01 = N0.getOperand(1); 864 SDValue N02 = N0.getOperand(2); 865 866 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2, 867 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1, 868 // IntRegs:i32:$src2) 869 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2) 870 // Pattern complexity = 9 cost = 1 size = 0. 871 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) { 872 SDValue N1 = N->getOperand(1); 873 if (N01 == N1) { 874 SDValue N2 = N->getOperand(2); 875 if (N000 == N2 && 876 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 && 877 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) { 878 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl, 879 MVT::i32, N000); 880 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl, 881 MVT::i32, 882 SDValue(SextNode, 0), 883 N1); 884 ReplaceUses(N, Result); 885 return Result; 886 } 887 } 888 } 889 890 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2, 891 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1, 892 // IntRegs:i32:$src2) 893 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2) 894 // Pattern complexity = 9 cost = 1 size = 0. 895 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) { 896 SDValue N1 = N->getOperand(1); 897 if (N01 == N1) { 898 SDValue N2 = N->getOperand(2); 899 if (N000 == N2 && 900 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 && 901 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) { 902 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl, 903 MVT::i32, N000); 904 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl, 905 MVT::i32, 906 SDValue(SextNode, 0), 907 N1); 908 ReplaceUses(N, Result); 909 return Result; 910 } 911 } 912 } 913 } 914 } 915 } 916 917 return SelectCode(N); 918 } 919 920 921 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) { 922 DebugLoc dl = N->getDebugLoc(); 923 SDValue Shift = N->getOperand(0); 924 925 // 926 // %conv.i = sext i32 %tmp1 to i64 927 // %conv2.i = sext i32 %add to i64 928 // %mul.i = mul nsw i64 %conv2.i, %conv.i 929 // %shr5.i = lshr i64 %mul.i, 32 930 // %conv3.i = trunc i64 %shr5.i to i32 931 // 932 // --- match with the following --- 933 // 934 // %conv3.i = mpy (%tmp1, %add) 935 // 936 // Trunc to i32. 937 if (N->getValueType(0) == MVT::i32) { 938 // Trunc from i64. 939 if (Shift.getNode()->getValueType(0) == MVT::i64) { 940 // Trunc child is logical shift right. 941 if (Shift.getOpcode() != ISD::SRL) { 942 return SelectCode(N); 943 } 944 945 SDValue ShiftOp0 = Shift.getOperand(0); 946 SDValue ShiftOp1 = Shift.getOperand(1); 947 948 // Shift by const 32 949 if (ShiftOp1.getOpcode() != ISD::Constant) { 950 return SelectCode(N); 951 } 952 953 int32_t ShiftConst = 954 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue(); 955 if (ShiftConst != 32) { 956 return SelectCode(N); 957 } 958 959 // Shifting a i64 signed multiply 960 SDValue Mul = ShiftOp0; 961 if (Mul.getOpcode() != ISD::MUL) { 962 return SelectCode(N); 963 } 964 965 SDValue MulOp0 = Mul.getOperand(0); 966 SDValue MulOp1 = Mul.getOperand(1); 967 968 SDValue OP0; 969 SDValue OP1; 970 971 // Handle sign_extend and sextload 972 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) { 973 SDValue Sext0 = MulOp0.getOperand(0); 974 if (Sext0.getNode()->getValueType(0) != MVT::i32) { 975 return SelectCode(N); 976 } 977 978 OP0 = Sext0; 979 } else if (MulOp0.getOpcode() == ISD::LOAD) { 980 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode()); 981 if (LD->getMemoryVT() != MVT::i32 || 982 LD->getExtensionType() != ISD::SEXTLOAD || 983 LD->getAddressingMode() != ISD::UNINDEXED) { 984 return SelectCode(N); 985 } 986 987 SDValue Chain = LD->getChain(); 988 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 989 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 990 MVT::Other, 991 LD->getBasePtr(), 992 TargetConst0, Chain), 0); 993 } else { 994 return SelectCode(N); 995 } 996 997 // Same goes for the second operand. 998 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) { 999 SDValue Sext1 = MulOp1.getOperand(0); 1000 if (Sext1.getNode()->getValueType(0) != MVT::i32) 1001 return SelectCode(N); 1002 1003 OP1 = Sext1; 1004 } else if (MulOp1.getOpcode() == ISD::LOAD) { 1005 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode()); 1006 if (LD->getMemoryVT() != MVT::i32 || 1007 LD->getExtensionType() != ISD::SEXTLOAD || 1008 LD->getAddressingMode() != ISD::UNINDEXED) { 1009 return SelectCode(N); 1010 } 1011 1012 SDValue Chain = LD->getChain(); 1013 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 1014 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 1015 MVT::Other, 1016 LD->getBasePtr(), 1017 TargetConst0, Chain), 0); 1018 } else { 1019 return SelectCode(N); 1020 } 1021 1022 // Generate a mpy instruction. 1023 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32, 1024 OP0, OP1); 1025 ReplaceUses(N, Result); 1026 return Result; 1027 } 1028 } 1029 1030 return SelectCode(N); 1031 } 1032 1033 1034 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) { 1035 DebugLoc dl = N->getDebugLoc(); 1036 if (N->getValueType(0) == MVT::i32) { 1037 SDValue Shl_0 = N->getOperand(0); 1038 SDValue Shl_1 = N->getOperand(1); 1039 // RHS is const. 1040 if (Shl_1.getOpcode() == ISD::Constant) { 1041 if (Shl_0.getOpcode() == ISD::MUL) { 1042 SDValue Mul_0 = Shl_0.getOperand(0); // Val 1043 SDValue Mul_1 = Shl_0.getOperand(1); // Const 1044 // RHS of mul is const. 1045 if (Mul_1.getOpcode() == ISD::Constant) { 1046 int32_t ShlConst = 1047 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue(); 1048 int32_t MulConst = 1049 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue(); 1050 int32_t ValConst = MulConst << ShlConst; 1051 SDValue Val = CurDAG->getTargetConstant(ValConst, 1052 MVT::i32); 1053 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode())) 1054 if (isInt<9>(CN->getSExtValue())) { 1055 SDNode* Result = 1056 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, 1057 MVT::i32, Mul_0, Val); 1058 ReplaceUses(N, Result); 1059 return Result; 1060 } 1061 1062 } 1063 } else if (Shl_0.getOpcode() == ISD::SUB) { 1064 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0 1065 SDValue Sub_1 = Shl_0.getOperand(1); // Val 1066 if (Sub_0.getOpcode() == ISD::Constant) { 1067 int32_t SubConst = 1068 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue(); 1069 if (SubConst == 0) { 1070 if (Sub_1.getOpcode() == ISD::SHL) { 1071 SDValue Shl2_0 = Sub_1.getOperand(0); // Val 1072 SDValue Shl2_1 = Sub_1.getOperand(1); // Const 1073 if (Shl2_1.getOpcode() == ISD::Constant) { 1074 int32_t ShlConst = 1075 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue(); 1076 int32_t Shl2Const = 1077 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue(); 1078 int32_t ValConst = 1 << (ShlConst+Shl2Const); 1079 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32); 1080 if (ConstantSDNode *CN = 1081 dyn_cast<ConstantSDNode>(Val.getNode())) 1082 if (isInt<9>(CN->getSExtValue())) { 1083 SDNode* Result = 1084 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32, 1085 Shl2_0, Val); 1086 ReplaceUses(N, Result); 1087 return Result; 1088 } 1089 } 1090 } 1091 } 1092 } 1093 } 1094 } 1095 } 1096 return SelectCode(N); 1097 } 1098 1099 1100 // 1101 // If there is an zero_extend followed an intrinsic in DAG (this means - the 1102 // result of the intrinsic is predicate); convert the zero_extend to 1103 // transfer instruction. 1104 // 1105 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be 1106 // converted into a MUX as predicate registers defined as 1 bit in the 1107 // compiler. Architecture defines them as 8-bit registers. 1108 // We want to preserve all the lower 8-bits and, not just 1 LSB bit. 1109 // 1110 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) { 1111 DebugLoc dl = N->getDebugLoc(); 1112 SDNode *IsIntrinsic = N->getOperand(0).getNode(); 1113 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) { 1114 unsigned ID = 1115 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue(); 1116 if (doesIntrinsicReturnPredicate(ID)) { 1117 // Now we need to differentiate target data types. 1118 if (N->getValueType(0) == MVT::i64) { 1119 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs). 1120 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 1121 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl, 1122 MVT::i32, 1123 SDValue(IsIntrinsic, 0)); 1124 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, 1125 MVT::i32, 1126 TargetConst0); 1127 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl, 1128 MVT::i64, MVT::Other, 1129 SDValue(Result_2, 0), 1130 SDValue(Result_1, 0)); 1131 ReplaceUses(N, Result_3); 1132 return Result_3; 1133 } 1134 if (N->getValueType(0) == MVT::i32) { 1135 // Convert the zero_extend to Rs = Pd 1136 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl, 1137 MVT::i32, 1138 SDValue(IsIntrinsic, 0)); 1139 ReplaceUses(N, RsPd); 1140 return RsPd; 1141 } 1142 llvm_unreachable("Unexpected value type"); 1143 } 1144 } 1145 return SelectCode(N); 1146 } 1147 1148 1149 // 1150 // Checking for intrinsics which have predicate registers as operand(s) 1151 // and lowering to the actual intrinsic. 1152 // 1153 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) { 1154 DebugLoc dl = N->getDebugLoc(); 1155 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 1156 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID); 1157 1158 // We are concerned with only those intrinsics that have predicate registers 1159 // as at least one of the operands. 1160 if (IntrinsicWithPred) { 1161 SmallVector<SDValue, 8> Ops; 1162 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred); 1163 const TargetRegisterInfo *TRI = TM.getRegisterInfo(); 1164 1165 // Iterate over all the operands of the intrinsics. 1166 // For PredRegs, do the transfer. 1167 // For Double/Int Regs, just preserve the value 1168 // For immediates, lower it. 1169 for (unsigned i = 1; i < N->getNumOperands(); ++i) { 1170 SDNode *Arg = N->getOperand(i).getNode(); 1171 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF); 1172 1173 if (RC == &Hexagon::IntRegsRegClass || 1174 RC == &Hexagon::DoubleRegsRegClass) { 1175 Ops.push_back(SDValue(Arg, 0)); 1176 } else if (RC == &Hexagon::PredRegsRegClass) { 1177 // Do the transfer. 1178 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1, 1179 SDValue(Arg, 0)); 1180 Ops.push_back(SDValue(PdRs,0)); 1181 } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) { 1182 // This is immediate operand. Lower it here making sure that we DO have 1183 // const SDNode for immediate value. 1184 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue(); 1185 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32); 1186 Ops.push_back(SDVal); 1187 } else { 1188 llvm_unreachable("Unimplemented"); 1189 } 1190 } 1191 EVT ReturnValueVT = N->getValueType(0); 1192 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl, 1193 ReturnValueVT, 1194 Ops.data(), Ops.size()); 1195 ReplaceUses(N, Result); 1196 return Result; 1197 } 1198 return SelectCode(N); 1199 } 1200 1201 // 1202 // Map floating point constant values. 1203 // 1204 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) { 1205 DebugLoc dl = N->getDebugLoc(); 1206 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N); 1207 APFloat APF = CN->getValueAPF(); 1208 if (N->getValueType(0) == MVT::f32) { 1209 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32, 1210 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32)); 1211 } 1212 else if (N->getValueType(0) == MVT::f64) { 1213 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64, 1214 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64)); 1215 } 1216 1217 return SelectCode(N); 1218 } 1219 1220 1221 // 1222 // Map predicate true (encoded as -1 in LLVM) to a XOR. 1223 // 1224 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) { 1225 DebugLoc dl = N->getDebugLoc(); 1226 if (N->getValueType(0) == MVT::i1) { 1227 SDNode* Result; 1228 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 1229 if (Val == -1) { 1230 // Create the IntReg = 1 node. 1231 SDNode* IntRegTFR = 1232 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32, 1233 CurDAG->getTargetConstant(0, MVT::i32)); 1234 1235 // Pd = IntReg 1236 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1, 1237 SDValue(IntRegTFR, 0)); 1238 1239 // not(Pd) 1240 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1, 1241 SDValue(Pd, 0)); 1242 1243 // xor(not(Pd)) 1244 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1, 1245 SDValue(Pd, 0), SDValue(NotPd, 0)); 1246 1247 // We have just built: 1248 // Rs = Pd 1249 // Pd = xor(not(Pd), Pd) 1250 1251 ReplaceUses(N, Result); 1252 return Result; 1253 } 1254 } 1255 1256 return SelectCode(N); 1257 } 1258 1259 1260 // 1261 // Map add followed by a asr -> asr +=. 1262 // 1263 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) { 1264 DebugLoc dl = N->getDebugLoc(); 1265 if (N->getValueType(0) != MVT::i32) { 1266 return SelectCode(N); 1267 } 1268 // Identify nodes of the form: add(asr(...)). 1269 SDNode* Src1 = N->getOperand(0).getNode(); 1270 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse() 1271 || Src1->getValueType(0) != MVT::i32) { 1272 return SelectCode(N); 1273 } 1274 1275 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that 1276 // Rd and Rd' are assigned to the same register 1277 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32, 1278 N->getOperand(1), 1279 Src1->getOperand(0), 1280 Src1->getOperand(1)); 1281 ReplaceUses(N, Result); 1282 1283 return Result; 1284 } 1285 1286 1287 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) { 1288 if (N->isMachineOpcode()) 1289 return NULL; // Already selected. 1290 1291 1292 switch (N->getOpcode()) { 1293 case ISD::Constant: 1294 return SelectConstant(N); 1295 1296 case ISD::ConstantFP: 1297 return SelectConstantFP(N); 1298 1299 case ISD::ADD: 1300 return SelectAdd(N); 1301 1302 case ISD::SHL: 1303 return SelectSHL(N); 1304 1305 case ISD::LOAD: 1306 return SelectLoad(N); 1307 1308 case ISD::STORE: 1309 return SelectStore(N); 1310 1311 case ISD::SELECT: 1312 return SelectSelect(N); 1313 1314 case ISD::TRUNCATE: 1315 return SelectTruncate(N); 1316 1317 case ISD::MUL: 1318 return SelectMul(N); 1319 1320 case ISD::ZERO_EXTEND: 1321 return SelectZeroExtend(N); 1322 1323 case ISD::INTRINSIC_WO_CHAIN: 1324 return SelectIntrinsicWOChain(N); 1325 } 1326 1327 return SelectCode(N); 1328 } 1329 1330 1331 // 1332 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way 1333 // to define these instructions. 1334 // 1335 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base, 1336 SDValue &Offset) { 1337 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1338 Addr.getOpcode() == ISD::TargetGlobalAddress) 1339 return false; // Direct calls. 1340 1341 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1342 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1343 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1344 return true; 1345 } 1346 Base = Addr; 1347 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1348 return true; 1349 } 1350 1351 1352 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base, 1353 SDValue &Offset) { 1354 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1355 Addr.getOpcode() == ISD::TargetGlobalAddress) 1356 return false; // Direct calls. 1357 1358 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1359 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1360 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1361 return (IsS11_0_Offset(Offset.getNode())); 1362 } 1363 Base = Addr; 1364 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1365 return (IsS11_0_Offset(Offset.getNode())); 1366 } 1367 1368 1369 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base, 1370 SDValue &Offset) { 1371 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1372 Addr.getOpcode() == ISD::TargetGlobalAddress) 1373 return false; // Direct calls. 1374 1375 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1376 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1377 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1378 return (IsS11_1_Offset(Offset.getNode())); 1379 } 1380 Base = Addr; 1381 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1382 return (IsS11_1_Offset(Offset.getNode())); 1383 } 1384 1385 1386 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base, 1387 SDValue &Offset) { 1388 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1389 Addr.getOpcode() == ISD::TargetGlobalAddress) 1390 return false; // Direct calls. 1391 1392 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1393 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1394 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1395 return (IsS11_2_Offset(Offset.getNode())); 1396 } 1397 Base = Addr; 1398 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1399 return (IsS11_2_Offset(Offset.getNode())); 1400 } 1401 1402 1403 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base, 1404 SDValue &Offset) { 1405 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1406 Addr.getOpcode() == ISD::TargetGlobalAddress) 1407 return false; // Direct calls. 1408 1409 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1410 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1411 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1412 return (IsU6_0_Offset(Offset.getNode())); 1413 } 1414 Base = Addr; 1415 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1416 return (IsU6_0_Offset(Offset.getNode())); 1417 } 1418 1419 1420 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base, 1421 SDValue &Offset) { 1422 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1423 Addr.getOpcode() == ISD::TargetGlobalAddress) 1424 return false; // Direct calls. 1425 1426 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1427 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1428 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1429 return (IsU6_1_Offset(Offset.getNode())); 1430 } 1431 Base = Addr; 1432 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1433 return (IsU6_1_Offset(Offset.getNode())); 1434 } 1435 1436 1437 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base, 1438 SDValue &Offset) { 1439 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1440 Addr.getOpcode() == ISD::TargetGlobalAddress) 1441 return false; // Direct calls. 1442 1443 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1444 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1445 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1446 return (IsU6_2_Offset(Offset.getNode())); 1447 } 1448 Base = Addr; 1449 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1450 return (IsU6_2_Offset(Offset.getNode())); 1451 } 1452 1453 1454 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base, 1455 SDValue &Offset) { 1456 1457 if (Addr.getOpcode() != ISD::ADD) { 1458 return(SelectADDRriS11_2(Addr, Base, Offset)); 1459 } 1460 1461 return SelectADDRriS11_2(Addr, Base, Offset); 1462 } 1463 1464 1465 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base, 1466 SDValue &Offset) { 1467 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1468 Addr.getOpcode() == ISD::TargetGlobalAddress) 1469 return false; // Direct calls. 1470 1471 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1472 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1473 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1474 return (IsS11_3_Offset(Offset.getNode())); 1475 } 1476 Base = Addr; 1477 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1478 return (IsS11_3_Offset(Offset.getNode())); 1479 } 1480 1481 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, 1482 SDValue &R2) { 1483 if (Addr.getOpcode() == ISD::FrameIndex) return false; 1484 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1485 Addr.getOpcode() == ISD::TargetGlobalAddress) 1486 return false; // Direct calls. 1487 1488 if (Addr.getOpcode() == ISD::ADD) { 1489 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 1490 if (isInt<13>(CN->getSExtValue())) 1491 return false; // Let the reg+imm pattern catch this! 1492 R1 = Addr.getOperand(0); 1493 R2 = Addr.getOperand(1); 1494 return true; 1495 } 1496 1497 R1 = Addr; 1498 1499 return true; 1500 } 1501 1502 1503 // Handle generic address case. It is accessed from inlined asm =m constraints, 1504 // which could have any kind of pointer. 1505 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr, 1506 SDValue &Base, SDValue &Offset) { 1507 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1508 Addr.getOpcode() == ISD::TargetGlobalAddress) 1509 return false; // Direct calls. 1510 1511 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1512 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1513 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1514 return true; 1515 } 1516 1517 if (Addr.getOpcode() == ISD::ADD) { 1518 Base = Addr.getOperand(0); 1519 Offset = Addr.getOperand(1); 1520 return true; 1521 } 1522 1523 Base = Addr; 1524 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1525 return true; 1526 } 1527 1528 1529 bool HexagonDAGToDAGISel:: 1530 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 1531 std::vector<SDValue> &OutOps) { 1532 SDValue Op0, Op1; 1533 1534 switch (ConstraintCode) { 1535 case 'o': // Offsetable. 1536 case 'v': // Not offsetable. 1537 default: return true; 1538 case 'm': // Memory. 1539 if (!SelectAddr(Op.getNode(), Op, Op0, Op1)) 1540 return true; 1541 break; 1542 } 1543 1544 OutOps.push_back(Op0); 1545 OutOps.push_back(Op1); 1546 return false; 1547 } 1548 1549 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const { 1550 unsigned UseCount = 0; 1551 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { 1552 UseCount++; 1553 } 1554 1555 return (UseCount <= 1); 1556 1557 } 1558 1559 //===--------------------------------------------------------------------===// 1560 // Return 'true' if use count of the global address is below threshold. 1561 //===--------------------------------------------------------------------===// 1562 bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const { 1563 assert(N->getOpcode() == ISD::TargetGlobalAddress && 1564 "Expecting a target global address"); 1565 1566 // Always try to fold the address. 1567 if (TM.getOptLevel() == CodeGenOpt::Aggressive) 1568 return true; 1569 1570 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N); 1571 DenseMap<const GlobalValue *, unsigned>::const_iterator GI = 1572 GlobalAddressUseCountMap.find(GA->getGlobal()); 1573 1574 if (GI == GlobalAddressUseCountMap.end()) 1575 return false; 1576 1577 return GI->second <= MaxNumOfUsesForConstExtenders; 1578 } 1579 1580 //===--------------------------------------------------------------------===// 1581 // Return true if the non GP-relative global address can be folded. 1582 //===--------------------------------------------------------------------===// 1583 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) { 1584 return foldGlobalAddressImpl(N, R, false); 1585 } 1586 1587 //===--------------------------------------------------------------------===// 1588 // Return true if the GP-relative global address can be folded. 1589 //===--------------------------------------------------------------------===// 1590 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) { 1591 return foldGlobalAddressImpl(N, R, true); 1592 } 1593 1594 //===--------------------------------------------------------------------===// 1595 // Fold offset of the global address if number of uses are below threshold. 1596 //===--------------------------------------------------------------------===// 1597 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R, 1598 bool ShouldLookForGP) { 1599 if (N.getOpcode() == ISD::ADD) { 1600 SDValue N0 = N.getOperand(0); 1601 SDValue N1 = N.getOperand(1); 1602 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) || 1603 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) { 1604 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1); 1605 GlobalAddressSDNode *GA = 1606 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0)); 1607 1608 if (Const && GA && 1609 (GA->getOpcode() == ISD::TargetGlobalAddress)) { 1610 if ((N0.getOpcode() == HexagonISD::CONST32) && 1611 !hasNumUsesBelowThresGA(GA)) 1612 return false; 1613 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(), 1614 Const->getDebugLoc(), 1615 N.getValueType(), 1616 GA->getOffset() + 1617 (uint64_t)Const->getSExtValue()); 1618 return true; 1619 } 1620 } 1621 } 1622 return false; 1623 } 1624