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