1 //===-- HexagonISelDAGToDAG.cpp - A dag to dag inst selector for Hexagon --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines an instruction selector for the Hexagon target.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "hexagon-isel"
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"
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"));
33 //===----------------------------------------------------------------------===//
34 // Instruction Selector Implementation
35 //===----------------------------------------------------------------------===//
38 void initializeHexagonDAGToDAGISelPass(PassRegistry&);
41 //===--------------------------------------------------------------------===//
42 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
43 /// instructions for SelectionDAG operations.
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;
51 // Keep a reference to HexagonTargetMachine.
52 const HexagonTargetMachine& TM;
53 DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap;
55 explicit HexagonDAGToDAGISel(const HexagonTargetMachine &targetmachine,
56 CodeGenOpt::Level OptLevel)
57 : SelectionDAGISel(targetmachine, OptLevel),
58 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
60 initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
62 bool hasNumUsesBelowThresGA(SDNode *N) const;
64 SDNode *Select(SDNode *N);
66 // Complex Pattern Selectors.
67 inline bool foldGlobalAddress(SDValue &N, SDValue &R);
68 inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
69 bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
70 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
71 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
72 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
73 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
74 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
75 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
76 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
77 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
78 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
79 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
81 virtual const char *getPassName() const {
82 return "Hexagon DAG->DAG Pattern Instruction Selection";
85 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
86 /// inline asm expressions.
87 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
89 std::vector<SDValue> &OutOps);
90 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
92 SDNode *SelectLoad(SDNode *N);
93 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl);
94 SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl);
95 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
97 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
99 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl);
100 SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl);
101 SDNode *SelectStore(SDNode *N);
102 SDNode *SelectSHL(SDNode *N);
103 SDNode *SelectSelect(SDNode *N);
104 SDNode *SelectTruncate(SDNode *N);
105 SDNode *SelectMul(SDNode *N);
106 SDNode *SelectZeroExtend(SDNode *N);
107 SDNode *SelectIntrinsicWOChain(SDNode *N);
108 SDNode *SelectIntrinsicWChain(SDNode *N);
109 SDNode *SelectConstant(SDNode *N);
110 SDNode *SelectConstantFP(SDNode *N);
111 SDNode *SelectAdd(SDNode *N);
112 bool isConstExtProfitable(SDNode *N) const;
114 // XformMskToBitPosU5Imm - Returns the bit position which
115 // the single bit 32 bit mask represents.
116 // Used in Clr and Set bit immediate memops.
117 SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
119 bitPos = Log2_32(Imm);
120 assert(bitPos >= 0 && bitPos < 32 &&
121 "Constant out of range for 32 BitPos Memops");
122 return CurDAG->getTargetConstant(bitPos, MVT::i32);
125 // XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
126 // mask represents. Used in Clr and Set bit immediate memops.
127 SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
128 return XformMskToBitPosU5Imm(Imm);
131 // XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
132 // mask represents. Used in Clr and Set bit immediate memops.
133 SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
134 return XformMskToBitPosU5Imm(Imm);
137 // Return true if there is exactly one bit set in V, i.e., if V is one of the
138 // following integers: 2^0, 2^1, ..., 2^31.
139 bool ImmIsSingleBit(uint32_t v) const {
140 uint32_t c = CountPopulation_64(v);
141 // Only return true if we counted 1 bit.
145 // XformM5ToU5Imm - Return a target constant with the specified value, of type
146 // i32 where the negative literal is transformed into a positive literal for
148 inline SDValue XformM5ToU5Imm(signed Imm) {
149 assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
150 return CurDAG->getTargetConstant( - Imm, MVT::i32);
154 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
155 // [1..128], used in cmpb.gtu instructions.
156 inline SDValue XformU7ToU7M1Imm(signed Imm) {
157 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
158 return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
161 // XformS8ToS8M1Imm - Return a target constant decremented by 1.
162 inline SDValue XformSToSM1Imm(signed Imm) {
163 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
166 // XformU8ToU8M1Imm - Return a target constant decremented by 1.
167 inline SDValue XformUToUM1Imm(unsigned Imm) {
168 assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
169 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
172 // Include the pieces autogenerated from the target description.
173 #include "HexagonGenDAGISel.inc"
175 } // end anonymous namespace
178 /// createHexagonISelDag - This pass converts a legalized DAG into a
179 /// Hexagon-specific DAG, ready for instruction scheduling.
181 FunctionPass *llvm::createHexagonISelDag(const HexagonTargetMachine &TM,
182 CodeGenOpt::Level OptLevel) {
183 return new HexagonDAGToDAGISel(TM, OptLevel);
186 static void initializePassOnce(PassRegistry &Registry) {
187 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
188 PassInfo *PI = new PassInfo(Name, "hexagon-isel",
189 &SelectionDAGISel::ID, 0, false, false);
190 Registry.registerPass(*PI, true);
193 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
194 CALL_ONCE_INITIALIZATION(initializePassOnce)
198 static bool IsS11_0_Offset(SDNode * S) {
199 ConstantSDNode *N = cast<ConstantSDNode>(S);
201 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
203 int64_t v = (int64_t)N->getSExtValue();
208 static bool IsS11_1_Offset(SDNode * S) {
209 ConstantSDNode *N = cast<ConstantSDNode>(S);
211 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
213 int64_t v = (int64_t)N->getSExtValue();
214 return isShiftedInt<11,1>(v);
218 static bool IsS11_2_Offset(SDNode * S) {
219 ConstantSDNode *N = cast<ConstantSDNode>(S);
221 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
223 int64_t v = (int64_t)N->getSExtValue();
224 return isShiftedInt<11,2>(v);
228 static bool IsS11_3_Offset(SDNode * S) {
229 ConstantSDNode *N = cast<ConstantSDNode>(S);
231 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
233 int64_t v = (int64_t)N->getSExtValue();
234 return isShiftedInt<11,3>(v);
238 static bool IsU6_0_Offset(SDNode * S) {
239 ConstantSDNode *N = cast<ConstantSDNode>(S);
241 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
243 int64_t v = (int64_t)N->getSExtValue();
248 static bool IsU6_1_Offset(SDNode * S) {
249 ConstantSDNode *N = cast<ConstantSDNode>(S);
251 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
253 int64_t v = (int64_t)N->getSExtValue();
254 return isShiftedUInt<6,1>(v);
258 static bool IsU6_2_Offset(SDNode * S) {
259 ConstantSDNode *N = cast<ConstantSDNode>(S);
261 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
263 int64_t v = (int64_t)N->getSExtValue();
264 return isShiftedUInt<6,2>(v);
268 // Intrinsics that return a a predicate.
269 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
274 case Intrinsic::hexagon_C2_cmpeq:
275 case Intrinsic::hexagon_C2_cmpgt:
276 case Intrinsic::hexagon_C2_cmpgtu:
277 case Intrinsic::hexagon_C2_cmpgtup:
278 case Intrinsic::hexagon_C2_cmpgtp:
279 case Intrinsic::hexagon_C2_cmpeqp:
280 case Intrinsic::hexagon_C2_bitsset:
281 case Intrinsic::hexagon_C2_bitsclr:
282 case Intrinsic::hexagon_C2_cmpeqi:
283 case Intrinsic::hexagon_C2_cmpgti:
284 case Intrinsic::hexagon_C2_cmpgtui:
285 case Intrinsic::hexagon_C2_cmpgei:
286 case Intrinsic::hexagon_C2_cmpgeui:
287 case Intrinsic::hexagon_C2_cmplt:
288 case Intrinsic::hexagon_C2_cmpltu:
289 case Intrinsic::hexagon_C2_bitsclri:
290 case Intrinsic::hexagon_C2_and:
291 case Intrinsic::hexagon_C2_or:
292 case Intrinsic::hexagon_C2_xor:
293 case Intrinsic::hexagon_C2_andn:
294 case Intrinsic::hexagon_C2_not:
295 case Intrinsic::hexagon_C2_orn:
296 case Intrinsic::hexagon_C2_pxfer_map:
297 case Intrinsic::hexagon_C2_any8:
298 case Intrinsic::hexagon_C2_all8:
299 case Intrinsic::hexagon_A2_vcmpbeq:
300 case Intrinsic::hexagon_A2_vcmpbgtu:
301 case Intrinsic::hexagon_A2_vcmpheq:
302 case Intrinsic::hexagon_A2_vcmphgt:
303 case Intrinsic::hexagon_A2_vcmphgtu:
304 case Intrinsic::hexagon_A2_vcmpweq:
305 case Intrinsic::hexagon_A2_vcmpwgt:
306 case Intrinsic::hexagon_A2_vcmpwgtu:
307 case Intrinsic::hexagon_C2_tfrrp:
308 case Intrinsic::hexagon_S2_tstbit_i:
309 case Intrinsic::hexagon_S2_tstbit_r:
315 // Intrinsics that have predicate operands.
316 static unsigned doesIntrinsicContainPredicate(unsigned ID)
321 case Intrinsic::hexagon_C2_tfrpr:
322 return Hexagon::TFR_RsPd;
323 case Intrinsic::hexagon_C2_and:
324 return Hexagon::AND_pp;
325 case Intrinsic::hexagon_C2_xor:
326 return Hexagon::XOR_pp;
327 case Intrinsic::hexagon_C2_or:
328 return Hexagon::OR_pp;
329 case Intrinsic::hexagon_C2_not:
330 return Hexagon::NOT_p;
331 case Intrinsic::hexagon_C2_any8:
332 return Hexagon::ANY_pp;
333 case Intrinsic::hexagon_C2_all8:
334 return Hexagon::ALL_pp;
335 case Intrinsic::hexagon_C2_vitpack:
336 return Hexagon::VITPACK_pp;
337 case Intrinsic::hexagon_C2_mask:
338 return Hexagon::MASK_p;
339 case Intrinsic::hexagon_C2_mux:
340 return Hexagon::MUX_rr;
342 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
343 // that's how it's mapped in q6protos.h.
344 case Intrinsic::hexagon_C2_muxir:
345 return Hexagon::MUX_ri;
347 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
348 // that's how it's mapped in q6protos.h.
349 case Intrinsic::hexagon_C2_muxri:
350 return Hexagon::MUX_ir;
352 case Intrinsic::hexagon_C2_muxii:
353 return Hexagon::MUX_ii;
354 case Intrinsic::hexagon_C2_vmux:
355 return Hexagon::VMUX_prr64;
356 case Intrinsic::hexagon_S2_valignrb:
357 return Hexagon::VALIGN_rrp;
358 case Intrinsic::hexagon_S2_vsplicerb:
359 return Hexagon::VSPLICE_rrp;
364 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
365 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
368 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
371 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
374 if (MemType == MVT::i8 && isInt<11>(Offset)) {
382 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
383 // lowering for GlobalAddress nodes has already turned it into a
386 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) {
387 SDValue Chain = LD->getChain();
388 SDNode* Const32 = LD->getBasePtr().getNode();
391 if (Const32->getOpcode() == HexagonISD::CONST32 &&
392 ISD::isNormalLoad(LD)) {
393 SDValue Base = Const32->getOperand(0);
394 EVT LoadedVT = LD->getMemoryVT();
395 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
396 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
397 MVT PointerTy = TLI->getPointerTy();
398 const GlobalValue* GV =
399 cast<GlobalAddressSDNode>(Base)->getGlobal();
401 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
402 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
405 // Figure out base + offset opcode
406 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
407 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
408 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
409 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
410 else llvm_unreachable("unknown memory type");
412 // Build indexed load.
413 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
414 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
420 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
421 MemOp[0] = LD->getMemOperand();
422 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
423 ReplaceUses(LD, Result);
428 return SelectCode(LD);
432 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
436 SDValue Chain = LD->getChain();
437 EVT LoadedVT = LD->getMemoryVT();
438 SDValue Base = LD->getBasePtr();
439 SDValue Offset = LD->getOffset();
440 SDNode *OffsetNode = Offset.getNode();
441 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
442 SDValue N1 = LD->getOperand(1);
446 const HexagonInstrInfo *TII =
447 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
448 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
449 N1.getNode()->getValueType(0) == MVT::i32) {
450 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
451 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
452 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
453 MVT::Other, Base, TargetConst,
455 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
456 SDValue(Result_1, 0));
457 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
458 MemOp[0] = LD->getMemOperand();
459 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
460 const SDValue Froms[] = { SDValue(LD, 0),
464 const SDValue Tos[] = { SDValue(Result_2, 0),
465 SDValue(Result_1, 1),
468 ReplaceUses(Froms, Tos, 3);
471 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
472 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
473 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
474 MVT::Other, Base, TargetConst0,
476 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
477 MVT::i64, SDValue(Result_1, 0));
478 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
479 MVT::i32, Base, TargetConstVal,
480 SDValue(Result_1, 1));
481 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
482 MemOp[0] = LD->getMemOperand();
483 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
484 const SDValue Froms[] = { SDValue(LD, 0),
488 const SDValue Tos[] = { SDValue(Result_2, 0),
489 SDValue(Result_3, 0),
492 ReplaceUses(Froms, Tos, 3);
495 return SelectCode(LD);
499 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
503 SDValue Chain = LD->getChain();
504 EVT LoadedVT = LD->getMemoryVT();
505 SDValue Base = LD->getBasePtr();
506 SDValue Offset = LD->getOffset();
507 SDNode *OffsetNode = Offset.getNode();
508 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
509 SDValue N1 = LD->getOperand(1);
513 const HexagonInstrInfo *TII =
514 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
515 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
516 N1.getNode()->getValueType(0) == MVT::i32) {
517 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
518 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
519 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
520 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
521 MVT::i32, MVT::Other, Base,
522 TargetConstVal, Chain);
523 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
525 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
526 MVT::i64, MVT::Other,
528 SDValue(Result_1,0));
529 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
530 MemOp[0] = LD->getMemOperand();
531 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
532 const SDValue Froms[] = { SDValue(LD, 0),
536 const SDValue Tos[] = { SDValue(Result_3, 0),
537 SDValue(Result_1, 1),
540 ReplaceUses(Froms, Tos, 3);
544 // Generate an indirect load.
545 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
546 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
547 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
549 Base, TargetConst0, Chain);
550 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
552 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
553 MVT::i64, MVT::Other,
555 SDValue(Result_1,0));
556 // Add offset to base.
557 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
558 Base, TargetConstVal,
559 SDValue(Result_1, 1));
560 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
561 MemOp[0] = LD->getMemOperand();
562 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
563 const SDValue Froms[] = { SDValue(LD, 0),
567 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
568 SDValue(Result_4, 0), // New address.
571 ReplaceUses(Froms, Tos, 3);
575 return SelectCode(LD);
579 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
580 SDValue Chain = LD->getChain();
581 SDValue Base = LD->getBasePtr();
582 SDValue Offset = LD->getOffset();
583 SDNode *OffsetNode = Offset.getNode();
584 // Get the constant value.
585 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
586 EVT LoadedVT = LD->getMemoryVT();
589 // Check for zero ext loads.
590 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
592 // Figure out the opcode.
593 const HexagonInstrInfo *TII =
594 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
595 if (LoadedVT == MVT::i64) {
596 if (TII->isValidAutoIncImm(LoadedVT, Val))
597 Opcode = Hexagon::POST_LDrid;
599 Opcode = Hexagon::LDrid;
600 } else if (LoadedVT == MVT::i32) {
601 if (TII->isValidAutoIncImm(LoadedVT, Val))
602 Opcode = Hexagon::POST_LDriw;
604 Opcode = Hexagon::LDriw;
605 } else if (LoadedVT == MVT::i16) {
606 if (TII->isValidAutoIncImm(LoadedVT, Val))
607 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
609 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
610 } else if (LoadedVT == MVT::i8) {
611 if (TII->isValidAutoIncImm(LoadedVT, Val))
612 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
614 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
616 llvm_unreachable("unknown memory type");
618 // For zero ext i64 loads, we need to add combine instructions.
619 if (LD->getValueType(0) == MVT::i64 &&
620 LD->getExtensionType() == ISD::ZEXTLOAD) {
621 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
623 if (LD->getValueType(0) == MVT::i64 &&
624 LD->getExtensionType() == ISD::SEXTLOAD) {
625 // Handle sign ext i64 loads.
626 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
628 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
629 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
630 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
632 MVT::i32, MVT::Other, Base,
633 TargetConstVal, Chain);
634 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
635 MemOp[0] = LD->getMemOperand();
636 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
637 const SDValue Froms[] = { SDValue(LD, 0),
641 const SDValue Tos[] = { SDValue(Result, 0),
645 ReplaceUses(Froms, Tos, 3);
648 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
649 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
650 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
652 MVT::Other, Base, TargetConst0,
654 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
655 Base, TargetConstVal,
656 SDValue(Result_1, 1));
657 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
658 MemOp[0] = LD->getMemOperand();
659 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
660 const SDValue Froms[] = { SDValue(LD, 0),
664 const SDValue Tos[] = { SDValue(Result_1, 0),
665 SDValue(Result_2, 0),
668 ReplaceUses(Froms, Tos, 3);
674 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
677 LoadSDNode *LD = cast<LoadSDNode>(N);
678 ISD::MemIndexedMode AM = LD->getAddressingMode();
680 // Handle indexed loads.
681 if (AM != ISD::UNINDEXED) {
682 result = SelectIndexedLoad(LD, dl);
684 result = SelectBaseOffsetLoad(LD, dl);
691 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
692 SDValue Chain = ST->getChain();
693 SDValue Base = ST->getBasePtr();
694 SDValue Offset = ST->getOffset();
695 SDValue Value = ST->getValue();
696 SDNode *OffsetNode = Offset.getNode();
697 // Get the constant value.
698 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
699 EVT StoredVT = ST->getMemoryVT();
701 // Offset value must be within representable range
702 // and must have correct alignment properties.
703 const HexagonInstrInfo *TII =
704 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
705 if (TII->isValidAutoIncImm(StoredVT, Val)) {
706 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
710 // Figure out the post inc version of opcode.
711 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
712 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
713 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
714 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
715 else llvm_unreachable("unknown memory type");
717 // Build post increment store.
718 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
720 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
721 MemOp[0] = ST->getMemOperand();
722 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
724 ReplaceUses(ST, Result);
725 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
729 // Note: Order of operands matches the def of instruction:
730 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
731 // and it differs for POST_ST* for instance.
732 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
736 // Figure out the opcode.
737 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
738 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
739 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
740 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
741 else llvm_unreachable("unknown memory type");
743 // Build regular store.
744 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
745 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
746 // Build splitted incriment instruction.
747 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
750 SDValue(Result_1, 0));
751 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
752 MemOp[0] = ST->getMemOperand();
753 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
755 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
756 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
761 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
763 SDValue Chain = ST->getChain();
764 SDNode* Const32 = ST->getBasePtr().getNode();
765 SDValue Value = ST->getValue();
768 // Try to lower stores of GlobalAdresses into indexed stores. Custom
769 // lowering for GlobalAddress nodes has already turned it into a
770 // CONST32. Avoid truncating stores for the moment. Post-inc stores
771 // do the same. Don't think there's a reason for it, so will file a
773 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
774 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
775 SDValue Base = Const32->getOperand(0);
776 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
777 EVT StoredVT = ST->getMemoryVT();
778 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
779 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
780 MVT PointerTy = TLI->getPointerTy();
781 const GlobalValue* GV =
782 cast<GlobalAddressSDNode>(Base)->getGlobal();
784 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
785 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
789 // Figure out base + offset opcode
790 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
791 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
792 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
793 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
794 else llvm_unreachable("unknown memory type");
796 SDValue Ops[] = {SDValue(NewBase,0),
797 CurDAG->getTargetConstant(Offset,PointerTy),
799 // build indexed store
800 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
802 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
803 MemOp[0] = ST->getMemOperand();
804 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
805 ReplaceUses(ST, Result);
811 return SelectCode(ST);
815 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
817 StoreSDNode *ST = cast<StoreSDNode>(N);
818 ISD::MemIndexedMode AM = ST->getAddressingMode();
820 // Handle indexed stores.
821 if (AM != ISD::UNINDEXED) {
822 return SelectIndexedStore(ST, dl);
825 return SelectBaseOffsetStore(ST, dl);
828 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
832 // %conv.i = sext i32 %tmp1 to i64
833 // %conv2.i = sext i32 %add to i64
834 // %mul.i = mul nsw i64 %conv2.i, %conv.i
836 // --- match with the following ---
838 // %mul.i = mpy (%tmp1, %add)
841 if (N->getValueType(0) == MVT::i64) {
842 // Shifting a i64 signed multiply.
843 SDValue MulOp0 = N->getOperand(0);
844 SDValue MulOp1 = N->getOperand(1);
849 // Handle sign_extend and sextload.
850 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
851 SDValue Sext0 = MulOp0.getOperand(0);
852 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
853 return SelectCode(N);
857 } else if (MulOp0.getOpcode() == ISD::LOAD) {
858 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
859 if (LD->getMemoryVT() != MVT::i32 ||
860 LD->getExtensionType() != ISD::SEXTLOAD ||
861 LD->getAddressingMode() != ISD::UNINDEXED) {
862 return SelectCode(N);
865 SDValue Chain = LD->getChain();
866 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
867 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
869 LD->getBasePtr(), TargetConst0,
872 return SelectCode(N);
875 // Same goes for the second operand.
876 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
877 SDValue Sext1 = MulOp1.getOperand(0);
878 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
879 return SelectCode(N);
883 } else if (MulOp1.getOpcode() == ISD::LOAD) {
884 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
885 if (LD->getMemoryVT() != MVT::i32 ||
886 LD->getExtensionType() != ISD::SEXTLOAD ||
887 LD->getAddressingMode() != ISD::UNINDEXED) {
888 return SelectCode(N);
891 SDValue Chain = LD->getChain();
892 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
893 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
895 LD->getBasePtr(), TargetConst0,
898 return SelectCode(N);
901 // Generate a mpy instruction.
902 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
904 ReplaceUses(N, Result);
908 return SelectCode(N);
912 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
914 SDValue N0 = N->getOperand(0);
915 if (N0.getOpcode() == ISD::SETCC) {
916 SDValue N00 = N0.getOperand(0);
917 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
918 SDValue N000 = N00.getOperand(0);
919 SDValue N001 = N00.getOperand(1);
920 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
921 SDValue N01 = N0.getOperand(1);
922 SDValue N02 = N0.getOperand(2);
924 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
925 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
926 // IntRegs:i32:$src2)
927 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
928 // Pattern complexity = 9 cost = 1 size = 0.
929 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
930 SDValue N1 = N->getOperand(1);
932 SDValue N2 = N->getOperand(2);
934 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
935 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
936 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
938 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
940 SDValue(SextNode, 0),
942 ReplaceUses(N, Result);
948 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
949 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
950 // IntRegs:i32:$src2)
951 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
952 // Pattern complexity = 9 cost = 1 size = 0.
953 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
954 SDValue N1 = N->getOperand(1);
956 SDValue N2 = N->getOperand(2);
958 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
959 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
960 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
962 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
964 SDValue(SextNode, 0),
966 ReplaceUses(N, Result);
975 return SelectCode(N);
979 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
981 SDValue Shift = N->getOperand(0);
984 // %conv.i = sext i32 %tmp1 to i64
985 // %conv2.i = sext i32 %add to i64
986 // %mul.i = mul nsw i64 %conv2.i, %conv.i
987 // %shr5.i = lshr i64 %mul.i, 32
988 // %conv3.i = trunc i64 %shr5.i to i32
990 // --- match with the following ---
992 // %conv3.i = mpy (%tmp1, %add)
995 if (N->getValueType(0) == MVT::i32) {
997 if (Shift.getNode()->getValueType(0) == MVT::i64) {
998 // Trunc child is logical shift right.
999 if (Shift.getOpcode() != ISD::SRL) {
1000 return SelectCode(N);
1003 SDValue ShiftOp0 = Shift.getOperand(0);
1004 SDValue ShiftOp1 = Shift.getOperand(1);
1006 // Shift by const 32
1007 if (ShiftOp1.getOpcode() != ISD::Constant) {
1008 return SelectCode(N);
1011 int32_t ShiftConst =
1012 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
1013 if (ShiftConst != 32) {
1014 return SelectCode(N);
1017 // Shifting a i64 signed multiply
1018 SDValue Mul = ShiftOp0;
1019 if (Mul.getOpcode() != ISD::MUL) {
1020 return SelectCode(N);
1023 SDValue MulOp0 = Mul.getOperand(0);
1024 SDValue MulOp1 = Mul.getOperand(1);
1029 // Handle sign_extend and sextload
1030 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
1031 SDValue Sext0 = MulOp0.getOperand(0);
1032 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
1033 return SelectCode(N);
1037 } else if (MulOp0.getOpcode() == ISD::LOAD) {
1038 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
1039 if (LD->getMemoryVT() != MVT::i32 ||
1040 LD->getExtensionType() != ISD::SEXTLOAD ||
1041 LD->getAddressingMode() != ISD::UNINDEXED) {
1042 return SelectCode(N);
1045 SDValue Chain = LD->getChain();
1046 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1047 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1050 TargetConst0, Chain), 0);
1052 return SelectCode(N);
1055 // Same goes for the second operand.
1056 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
1057 SDValue Sext1 = MulOp1.getOperand(0);
1058 if (Sext1.getNode()->getValueType(0) != MVT::i32)
1059 return SelectCode(N);
1062 } else if (MulOp1.getOpcode() == ISD::LOAD) {
1063 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
1064 if (LD->getMemoryVT() != MVT::i32 ||
1065 LD->getExtensionType() != ISD::SEXTLOAD ||
1066 LD->getAddressingMode() != ISD::UNINDEXED) {
1067 return SelectCode(N);
1070 SDValue Chain = LD->getChain();
1071 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1072 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1075 TargetConst0, Chain), 0);
1077 return SelectCode(N);
1080 // Generate a mpy instruction.
1081 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
1083 ReplaceUses(N, Result);
1088 return SelectCode(N);
1092 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
1094 if (N->getValueType(0) == MVT::i32) {
1095 SDValue Shl_0 = N->getOperand(0);
1096 SDValue Shl_1 = N->getOperand(1);
1098 if (Shl_1.getOpcode() == ISD::Constant) {
1099 if (Shl_0.getOpcode() == ISD::MUL) {
1100 SDValue Mul_0 = Shl_0.getOperand(0); // Val
1101 SDValue Mul_1 = Shl_0.getOperand(1); // Const
1102 // RHS of mul is const.
1103 if (Mul_1.getOpcode() == ISD::Constant) {
1105 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1107 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1108 int32_t ValConst = MulConst << ShlConst;
1109 SDValue Val = CurDAG->getTargetConstant(ValConst,
1111 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1112 if (isInt<9>(CN->getSExtValue())) {
1114 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
1115 MVT::i32, Mul_0, Val);
1116 ReplaceUses(N, Result);
1121 } else if (Shl_0.getOpcode() == ISD::SUB) {
1122 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1123 SDValue Sub_1 = Shl_0.getOperand(1); // Val
1124 if (Sub_0.getOpcode() == ISD::Constant) {
1126 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1127 if (SubConst == 0) {
1128 if (Sub_1.getOpcode() == ISD::SHL) {
1129 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1130 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1131 if (Shl2_1.getOpcode() == ISD::Constant) {
1133 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1135 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1136 int32_t ValConst = 1 << (ShlConst+Shl2Const);
1137 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1138 if (ConstantSDNode *CN =
1139 dyn_cast<ConstantSDNode>(Val.getNode()))
1140 if (isInt<9>(CN->getSExtValue())) {
1142 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
1144 ReplaceUses(N, Result);
1154 return SelectCode(N);
1159 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1160 // result of the intrinsic is predicate); convert the zero_extend to
1161 // transfer instruction.
1163 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1164 // converted into a MUX as predicate registers defined as 1 bit in the
1165 // compiler. Architecture defines them as 8-bit registers.
1166 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1168 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1170 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1171 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1173 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1174 if (doesIntrinsicReturnPredicate(ID)) {
1175 // Now we need to differentiate target data types.
1176 if (N->getValueType(0) == MVT::i64) {
1177 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1178 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1179 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1181 SDValue(IsIntrinsic, 0));
1182 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
1185 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
1186 MVT::i64, MVT::Other,
1187 SDValue(Result_2, 0),
1188 SDValue(Result_1, 0));
1189 ReplaceUses(N, Result_3);
1192 if (N->getValueType(0) == MVT::i32) {
1193 // Convert the zero_extend to Rs = Pd
1194 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1196 SDValue(IsIntrinsic, 0));
1197 ReplaceUses(N, RsPd);
1200 llvm_unreachable("Unexpected value type");
1203 return SelectCode(N);
1208 // Checking for intrinsics which have predicate registers as operand(s)
1209 // and lowering to the actual intrinsic.
1211 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1213 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1214 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
1216 // We are concerned with only those intrinsics that have predicate registers
1217 // as at least one of the operands.
1218 const HexagonInstrInfo *TII =
1219 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
1220 if (IntrinsicWithPred) {
1221 SmallVector<SDValue, 8> Ops;
1222 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
1223 const TargetRegisterInfo *TRI = TM.getRegisterInfo();
1225 // Iterate over all the operands of the intrinsics.
1226 // For PredRegs, do the transfer.
1227 // For Double/Int Regs, just preserve the value
1228 // For immediates, lower it.
1229 for (unsigned i = 1; i < N->getNumOperands(); ++i) {
1230 SDNode *Arg = N->getOperand(i).getNode();
1231 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF);
1233 if (RC == &Hexagon::IntRegsRegClass ||
1234 RC == &Hexagon::DoubleRegsRegClass) {
1235 Ops.push_back(SDValue(Arg, 0));
1236 } else if (RC == &Hexagon::PredRegsRegClass) {
1238 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1240 Ops.push_back(SDValue(PdRs,0));
1241 } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
1242 // This is immediate operand. Lower it here making sure that we DO have
1243 // const SDNode for immediate value.
1244 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
1245 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
1246 Ops.push_back(SDVal);
1248 llvm_unreachable("Unimplemented");
1251 EVT ReturnValueVT = N->getValueType(0);
1252 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
1253 ReturnValueVT, Ops);
1254 ReplaceUses(N, Result);
1257 return SelectCode(N);
1261 // Map floating point constant values.
1263 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1265 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1266 APFloat APF = CN->getValueAPF();
1267 if (N->getValueType(0) == MVT::f32) {
1268 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1269 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1271 else if (N->getValueType(0) == MVT::f64) {
1272 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1273 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1276 return SelectCode(N);
1281 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1283 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1285 if (N->getValueType(0) == MVT::i1) {
1287 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1289 // Create the IntReg = 1 node.
1291 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1292 CurDAG->getTargetConstant(0, MVT::i32));
1295 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1296 SDValue(IntRegTFR, 0));
1299 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
1303 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1304 SDValue(Pd, 0), SDValue(NotPd, 0));
1306 // We have just built:
1308 // Pd = xor(not(Pd), Pd)
1310 ReplaceUses(N, Result);
1315 return SelectCode(N);
1320 // Map add followed by a asr -> asr +=.
1322 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1324 if (N->getValueType(0) != MVT::i32) {
1325 return SelectCode(N);
1327 // Identify nodes of the form: add(asr(...)).
1328 SDNode* Src1 = N->getOperand(0).getNode();
1329 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1330 || Src1->getValueType(0) != MVT::i32) {
1331 return SelectCode(N);
1334 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1335 // Rd and Rd' are assigned to the same register
1336 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
1338 Src1->getOperand(0),
1339 Src1->getOperand(1));
1340 ReplaceUses(N, Result);
1346 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1347 if (N->isMachineOpcode())
1348 return NULL; // Already selected.
1351 switch (N->getOpcode()) {
1353 return SelectConstant(N);
1355 case ISD::ConstantFP:
1356 return SelectConstantFP(N);
1359 return SelectAdd(N);
1362 return SelectSHL(N);
1365 return SelectLoad(N);
1368 return SelectStore(N);
1371 return SelectSelect(N);
1374 return SelectTruncate(N);
1377 return SelectMul(N);
1379 case ISD::ZERO_EXTEND:
1380 return SelectZeroExtend(N);
1382 case ISD::INTRINSIC_WO_CHAIN:
1383 return SelectIntrinsicWOChain(N);
1386 return SelectCode(N);
1391 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1392 // to define these instructions.
1394 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1396 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1397 Addr.getOpcode() == ISD::TargetGlobalAddress)
1398 return false; // Direct calls.
1400 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1401 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1402 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1406 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1411 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1413 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1414 Addr.getOpcode() == ISD::TargetGlobalAddress)
1415 return false; // Direct calls.
1417 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1418 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1419 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1420 return (IsS11_0_Offset(Offset.getNode()));
1423 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1424 return (IsS11_0_Offset(Offset.getNode()));
1428 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1430 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1431 Addr.getOpcode() == ISD::TargetGlobalAddress)
1432 return false; // Direct calls.
1434 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1435 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1436 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1437 return (IsS11_1_Offset(Offset.getNode()));
1440 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1441 return (IsS11_1_Offset(Offset.getNode()));
1445 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1447 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1448 Addr.getOpcode() == ISD::TargetGlobalAddress)
1449 return false; // Direct calls.
1451 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1452 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1453 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1454 return (IsS11_2_Offset(Offset.getNode()));
1457 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1458 return (IsS11_2_Offset(Offset.getNode()));
1462 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1464 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1465 Addr.getOpcode() == ISD::TargetGlobalAddress)
1466 return false; // Direct calls.
1468 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1469 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1470 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1471 return (IsU6_0_Offset(Offset.getNode()));
1474 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1475 return (IsU6_0_Offset(Offset.getNode()));
1479 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1481 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1482 Addr.getOpcode() == ISD::TargetGlobalAddress)
1483 return false; // Direct calls.
1485 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1486 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1487 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1488 return (IsU6_1_Offset(Offset.getNode()));
1491 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1492 return (IsU6_1_Offset(Offset.getNode()));
1496 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1498 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1499 Addr.getOpcode() == ISD::TargetGlobalAddress)
1500 return false; // Direct calls.
1502 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1503 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1504 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1505 return (IsU6_2_Offset(Offset.getNode()));
1508 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1509 return (IsU6_2_Offset(Offset.getNode()));
1513 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1516 if (Addr.getOpcode() != ISD::ADD) {
1517 return(SelectADDRriS11_2(Addr, Base, Offset));
1520 return SelectADDRriS11_2(Addr, Base, Offset);
1524 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1526 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1527 Addr.getOpcode() == ISD::TargetGlobalAddress)
1528 return false; // Direct calls.
1530 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1531 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1532 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1533 return (IsS11_3_Offset(Offset.getNode()));
1536 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1537 return (IsS11_3_Offset(Offset.getNode()));
1540 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1542 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1543 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1544 Addr.getOpcode() == ISD::TargetGlobalAddress)
1545 return false; // Direct calls.
1547 if (Addr.getOpcode() == ISD::ADD) {
1548 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1549 if (isInt<13>(CN->getSExtValue()))
1550 return false; // Let the reg+imm pattern catch this!
1551 R1 = Addr.getOperand(0);
1552 R2 = Addr.getOperand(1);
1562 // Handle generic address case. It is accessed from inlined asm =m constraints,
1563 // which could have any kind of pointer.
1564 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1565 SDValue &Base, SDValue &Offset) {
1566 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1567 Addr.getOpcode() == ISD::TargetGlobalAddress)
1568 return false; // Direct calls.
1570 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1571 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1572 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1576 if (Addr.getOpcode() == ISD::ADD) {
1577 Base = Addr.getOperand(0);
1578 Offset = Addr.getOperand(1);
1583 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1588 bool HexagonDAGToDAGISel::
1589 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1590 std::vector<SDValue> &OutOps) {
1593 switch (ConstraintCode) {
1594 case 'o': // Offsetable.
1595 case 'v': // Not offsetable.
1596 default: return true;
1597 case 'm': // Memory.
1598 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1603 OutOps.push_back(Op0);
1604 OutOps.push_back(Op1);
1608 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
1609 unsigned UseCount = 0;
1610 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
1614 return (UseCount <= 1);
1618 //===--------------------------------------------------------------------===//
1619 // Return 'true' if use count of the global address is below threshold.
1620 //===--------------------------------------------------------------------===//
1621 bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const {
1622 assert(N->getOpcode() == ISD::TargetGlobalAddress &&
1623 "Expecting a target global address");
1625 // Always try to fold the address.
1626 if (TM.getOptLevel() == CodeGenOpt::Aggressive)
1629 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
1630 DenseMap<const GlobalValue *, unsigned>::const_iterator GI =
1631 GlobalAddressUseCountMap.find(GA->getGlobal());
1633 if (GI == GlobalAddressUseCountMap.end())
1636 return GI->second <= MaxNumOfUsesForConstExtenders;
1639 //===--------------------------------------------------------------------===//
1640 // Return true if the non GP-relative global address can be folded.
1641 //===--------------------------------------------------------------------===//
1642 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
1643 return foldGlobalAddressImpl(N, R, false);
1646 //===--------------------------------------------------------------------===//
1647 // Return true if the GP-relative global address can be folded.
1648 //===--------------------------------------------------------------------===//
1649 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
1650 return foldGlobalAddressImpl(N, R, true);
1653 //===--------------------------------------------------------------------===//
1654 // Fold offset of the global address if number of uses are below threshold.
1655 //===--------------------------------------------------------------------===//
1656 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
1657 bool ShouldLookForGP) {
1658 if (N.getOpcode() == ISD::ADD) {
1659 SDValue N0 = N.getOperand(0);
1660 SDValue N1 = N.getOperand(1);
1661 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
1662 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
1663 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
1664 GlobalAddressSDNode *GA =
1665 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
1668 (GA->getOpcode() == ISD::TargetGlobalAddress)) {
1669 if ((N0.getOpcode() == HexagonISD::CONST32) &&
1670 !hasNumUsesBelowThresGA(GA))
1672 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
1676 (uint64_t)Const->getSExtValue());