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 //===----------------------------------------------------------------------===//
15 #include "HexagonISelLowering.h"
16 #include "HexagonTargetMachine.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/CodeGen/SelectionDAGISel.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/Support/CommandLine.h"
21 #include "llvm/Support/Compiler.h"
22 #include "llvm/Support/Debug.h"
25 #define DEBUG_TYPE "hexagon-isel"
29 MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders",
30 cl::Hidden, cl::init(2),
31 cl::desc("Maximum number of uses of a global address such that we still us a"
32 "constant extended instruction"));
34 //===----------------------------------------------------------------------===//
35 // Instruction Selector Implementation
36 //===----------------------------------------------------------------------===//
39 void initializeHexagonDAGToDAGISelPass(PassRegistry&);
42 //===--------------------------------------------------------------------===//
43 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
44 /// instructions for SelectionDAG operations.
47 class HexagonDAGToDAGISel : public SelectionDAGISel {
48 /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
49 /// make the right decision when generating code for different targets.
50 const HexagonSubtarget &Subtarget;
52 // Keep a reference to HexagonTargetMachine.
53 const HexagonTargetMachine& TM;
54 DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap;
56 explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine,
57 CodeGenOpt::Level OptLevel)
58 : SelectionDAGISel(targetmachine, OptLevel),
59 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
61 initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
63 bool hasNumUsesBelowThresGA(SDNode *N) const;
65 SDNode *Select(SDNode *N) override;
67 // Complex Pattern Selectors.
68 inline bool foldGlobalAddress(SDValue &N, SDValue &R);
69 inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
70 bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
71 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
72 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
73 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
74 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
75 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
76 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
77 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
78 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
79 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
80 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
82 const char *getPassName() const override {
83 return "Hexagon DAG->DAG Pattern Instruction Selection";
86 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
87 /// inline asm expressions.
88 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
90 std::vector<SDValue> &OutOps) override;
91 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
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,
98 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
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 *SelectSelect(SDNode *N);
105 SDNode *SelectTruncate(SDNode *N);
106 SDNode *SelectMul(SDNode *N);
107 SDNode *SelectZeroExtend(SDNode *N);
108 SDNode *SelectIntrinsicWOChain(SDNode *N);
109 SDNode *SelectIntrinsicWChain(SDNode *N);
110 SDNode *SelectConstant(SDNode *N);
111 SDNode *SelectConstantFP(SDNode *N);
112 SDNode *SelectAdd(SDNode *N);
113 bool isConstExtProfitable(SDNode *N) const;
115 // XformMskToBitPosU5Imm - Returns the bit position which
116 // the single bit 32 bit mask represents.
117 // Used in Clr and Set bit immediate memops.
118 SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
120 bitPos = Log2_32(Imm);
121 assert(bitPos >= 0 && bitPos < 32 &&
122 "Constant out of range for 32 BitPos Memops");
123 return CurDAG->getTargetConstant(bitPos, MVT::i32);
126 // XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
127 // mask represents. Used in Clr and Set bit immediate memops.
128 SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
129 return XformMskToBitPosU5Imm(Imm);
132 // XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
133 // mask represents. Used in Clr and Set bit immediate memops.
134 SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
135 return XformMskToBitPosU5Imm(Imm);
138 // Return true if there is exactly one bit set in V, i.e., if V is one of the
139 // following integers: 2^0, 2^1, ..., 2^31.
140 bool ImmIsSingleBit(uint32_t v) const {
141 uint32_t c = CountPopulation_64(v);
142 // Only return true if we counted 1 bit.
146 // XformM5ToU5Imm - Return a target constant with the specified value, of type
147 // i32 where the negative literal is transformed into a positive literal for
149 inline SDValue XformM5ToU5Imm(signed Imm) {
150 assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
151 return CurDAG->getTargetConstant( - Imm, MVT::i32);
155 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
156 // [1..128], used in cmpb.gtu instructions.
157 inline SDValue XformU7ToU7M1Imm(signed Imm) {
158 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
159 return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
162 // XformS8ToS8M1Imm - Return a target constant decremented by 1.
163 inline SDValue XformSToSM1Imm(signed Imm) {
164 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
167 // XformU8ToU8M1Imm - Return a target constant decremented by 1.
168 inline SDValue XformUToUM1Imm(unsigned Imm) {
169 assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
170 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
173 // Include the pieces autogenerated from the target description.
174 #include "HexagonGenDAGISel.inc"
176 } // end anonymous namespace
179 /// createHexagonISelDag - This pass converts a legalized DAG into a
180 /// Hexagon-specific DAG, ready for instruction scheduling.
182 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM,
183 CodeGenOpt::Level OptLevel) {
184 return new HexagonDAGToDAGISel(TM, OptLevel);
187 static void initializePassOnce(PassRegistry &Registry) {
188 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
189 PassInfo *PI = new PassInfo(Name, "hexagon-isel",
190 &SelectionDAGISel::ID, nullptr, false, false);
191 Registry.registerPass(*PI, true);
194 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
195 CALL_ONCE_INITIALIZATION(initializePassOnce)
199 static bool IsS11_0_Offset(SDNode * S) {
200 ConstantSDNode *N = cast<ConstantSDNode>(S);
202 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
204 int64_t v = (int64_t)N->getSExtValue();
209 static bool IsS11_1_Offset(SDNode * S) {
210 ConstantSDNode *N = cast<ConstantSDNode>(S);
212 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
214 int64_t v = (int64_t)N->getSExtValue();
215 return isShiftedInt<11,1>(v);
219 static bool IsS11_2_Offset(SDNode * S) {
220 ConstantSDNode *N = cast<ConstantSDNode>(S);
222 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
224 int64_t v = (int64_t)N->getSExtValue();
225 return isShiftedInt<11,2>(v);
229 static bool IsS11_3_Offset(SDNode * S) {
230 ConstantSDNode *N = cast<ConstantSDNode>(S);
232 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
234 int64_t v = (int64_t)N->getSExtValue();
235 return isShiftedInt<11,3>(v);
239 static bool IsU6_0_Offset(SDNode * S) {
240 ConstantSDNode *N = cast<ConstantSDNode>(S);
242 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
244 int64_t v = (int64_t)N->getSExtValue();
249 static bool IsU6_1_Offset(SDNode * S) {
250 ConstantSDNode *N = cast<ConstantSDNode>(S);
252 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
254 int64_t v = (int64_t)N->getSExtValue();
255 return isShiftedUInt<6,1>(v);
259 static bool IsU6_2_Offset(SDNode * S) {
260 ConstantSDNode *N = cast<ConstantSDNode>(S);
262 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
264 int64_t v = (int64_t)N->getSExtValue();
265 return isShiftedUInt<6,2>(v);
269 // Intrinsics that return a a predicate.
270 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
275 case Intrinsic::hexagon_C2_cmpeq:
276 case Intrinsic::hexagon_C2_cmpgt:
277 case Intrinsic::hexagon_C2_cmpgtu:
278 case Intrinsic::hexagon_C2_cmpgtup:
279 case Intrinsic::hexagon_C2_cmpgtp:
280 case Intrinsic::hexagon_C2_cmpeqp:
281 case Intrinsic::hexagon_C2_bitsset:
282 case Intrinsic::hexagon_C2_bitsclr:
283 case Intrinsic::hexagon_C2_cmpeqi:
284 case Intrinsic::hexagon_C2_cmpgti:
285 case Intrinsic::hexagon_C2_cmpgtui:
286 case Intrinsic::hexagon_C2_cmpgei:
287 case Intrinsic::hexagon_C2_cmpgeui:
288 case Intrinsic::hexagon_C2_cmplt:
289 case Intrinsic::hexagon_C2_cmpltu:
290 case Intrinsic::hexagon_C2_bitsclri:
291 case Intrinsic::hexagon_C2_and:
292 case Intrinsic::hexagon_C2_or:
293 case Intrinsic::hexagon_C2_xor:
294 case Intrinsic::hexagon_C2_andn:
295 case Intrinsic::hexagon_C2_not:
296 case Intrinsic::hexagon_C2_orn:
297 case Intrinsic::hexagon_C2_pxfer_map:
298 case Intrinsic::hexagon_C2_any8:
299 case Intrinsic::hexagon_C2_all8:
300 case Intrinsic::hexagon_A2_vcmpbeq:
301 case Intrinsic::hexagon_A2_vcmpbgtu:
302 case Intrinsic::hexagon_A2_vcmpheq:
303 case Intrinsic::hexagon_A2_vcmphgt:
304 case Intrinsic::hexagon_A2_vcmphgtu:
305 case Intrinsic::hexagon_A2_vcmpweq:
306 case Intrinsic::hexagon_A2_vcmpwgt:
307 case Intrinsic::hexagon_A2_vcmpwgtu:
308 case Intrinsic::hexagon_C2_tfrrp:
309 case Intrinsic::hexagon_S2_tstbit_i:
310 case Intrinsic::hexagon_S2_tstbit_r:
316 // Intrinsics that have predicate operands.
317 static unsigned doesIntrinsicContainPredicate(unsigned ID)
322 case Intrinsic::hexagon_C2_tfrpr:
323 return Hexagon::TFR_RsPd;
324 case Intrinsic::hexagon_C2_and:
325 return Hexagon::AND_pp;
326 case Intrinsic::hexagon_C2_xor:
327 return Hexagon::XOR_pp;
328 case Intrinsic::hexagon_C2_or:
329 return Hexagon::OR_pp;
330 case Intrinsic::hexagon_C2_not:
331 return Hexagon::NOT_p;
332 case Intrinsic::hexagon_C2_any8:
333 return Hexagon::ANY_pp;
334 case Intrinsic::hexagon_C2_all8:
335 return Hexagon::ALL_pp;
336 case Intrinsic::hexagon_C2_vitpack:
337 return Hexagon::VITPACK_pp;
338 case Intrinsic::hexagon_C2_mask:
339 return Hexagon::MASK_p;
340 case Intrinsic::hexagon_C2_mux:
341 return Hexagon::MUX_rr;
343 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
344 // that's how it's mapped in q6protos.h.
345 case Intrinsic::hexagon_C2_muxir:
346 return Hexagon::MUX_ri;
348 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
349 // that's how it's mapped in q6protos.h.
350 case Intrinsic::hexagon_C2_muxri:
351 return Hexagon::MUX_ir;
353 case Intrinsic::hexagon_C2_muxii:
354 return Hexagon::MUX_ii;
355 case Intrinsic::hexagon_C2_vmux:
356 return Hexagon::VMUX_prr64;
357 case Intrinsic::hexagon_S2_valignrb:
358 return Hexagon::VALIGN_rrp;
359 case Intrinsic::hexagon_S2_vsplicerb:
360 return Hexagon::VSPLICE_rrp;
365 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
366 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
369 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
372 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
375 if (MemType == MVT::i8 && isInt<11>(Offset)) {
383 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
384 // lowering for GlobalAddress nodes has already turned it into a
387 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) {
388 SDValue Chain = LD->getChain();
389 SDNode* Const32 = LD->getBasePtr().getNode();
392 if (Const32->getOpcode() == HexagonISD::CONST32 &&
393 ISD::isNormalLoad(LD)) {
394 SDValue Base = Const32->getOperand(0);
395 EVT LoadedVT = LD->getMemoryVT();
396 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
397 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
398 MVT PointerTy = getTargetLowering()->getPointerTy();
399 const GlobalValue* GV =
400 cast<GlobalAddressSDNode>(Base)->getGlobal();
402 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
403 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
406 // Figure out base + offset opcode
407 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
408 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
409 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
410 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
411 else llvm_unreachable("unknown memory type");
413 // Build indexed load.
414 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
415 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
421 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
422 MemOp[0] = LD->getMemOperand();
423 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
424 ReplaceUses(LD, Result);
429 return SelectCode(LD);
433 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
437 SDValue Chain = LD->getChain();
438 EVT LoadedVT = LD->getMemoryVT();
439 SDValue Base = LD->getBasePtr();
440 SDValue Offset = LD->getOffset();
441 SDNode *OffsetNode = Offset.getNode();
442 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
443 SDValue N1 = LD->getOperand(1);
447 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
448 N1.getNode()->getValueType(0) == MVT::i32) {
449 const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
450 TM.getSubtargetImpl()->getInstrInfo());
451 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
452 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
453 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
454 MVT::Other, Base, TargetConst,
456 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
457 SDValue(Result_1, 0));
458 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
459 MemOp[0] = LD->getMemOperand();
460 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
461 const SDValue Froms[] = { SDValue(LD, 0),
465 const SDValue Tos[] = { SDValue(Result_2, 0),
466 SDValue(Result_1, 1),
469 ReplaceUses(Froms, Tos, 3);
472 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
473 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
474 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
475 MVT::Other, Base, TargetConst0,
477 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
478 MVT::i64, SDValue(Result_1, 0));
479 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
480 MVT::i32, Base, TargetConstVal,
481 SDValue(Result_1, 1));
482 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
483 MemOp[0] = LD->getMemOperand();
484 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
485 const SDValue Froms[] = { SDValue(LD, 0),
489 const SDValue Tos[] = { SDValue(Result_2, 0),
490 SDValue(Result_3, 0),
493 ReplaceUses(Froms, Tos, 3);
496 return SelectCode(LD);
500 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
504 SDValue Chain = LD->getChain();
505 EVT LoadedVT = LD->getMemoryVT();
506 SDValue Base = LD->getBasePtr();
507 SDValue Offset = LD->getOffset();
508 SDNode *OffsetNode = Offset.getNode();
509 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
510 SDValue N1 = LD->getOperand(1);
514 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
515 N1.getNode()->getValueType(0) == MVT::i32) {
516 const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
517 TM.getSubtargetImpl()->getInstrInfo());
518 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
519 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
520 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
521 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
522 MVT::i32, MVT::Other, Base,
523 TargetConstVal, Chain);
524 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
526 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
527 MVT::i64, MVT::Other,
529 SDValue(Result_1,0));
530 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
531 MemOp[0] = LD->getMemOperand();
532 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
533 const SDValue Froms[] = { SDValue(LD, 0),
537 const SDValue Tos[] = { SDValue(Result_3, 0),
538 SDValue(Result_1, 1),
541 ReplaceUses(Froms, Tos, 3);
545 // Generate an indirect load.
546 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
547 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
548 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
550 Base, TargetConst0, Chain);
551 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
553 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
554 MVT::i64, MVT::Other,
556 SDValue(Result_1,0));
557 // Add offset to base.
558 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
559 Base, TargetConstVal,
560 SDValue(Result_1, 1));
561 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
562 MemOp[0] = LD->getMemOperand();
563 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
564 const SDValue Froms[] = { SDValue(LD, 0),
568 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
569 SDValue(Result_4, 0), // New address.
572 ReplaceUses(Froms, Tos, 3);
576 return SelectCode(LD);
580 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
581 SDValue Chain = LD->getChain();
582 SDValue Base = LD->getBasePtr();
583 SDValue Offset = LD->getOffset();
584 SDNode *OffsetNode = Offset.getNode();
585 // Get the constant value.
586 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
587 EVT LoadedVT = LD->getMemoryVT();
590 // Check for zero ext loads.
591 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
593 // Figure out the opcode.
594 const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
595 TM.getSubtargetImpl()->getInstrInfo());
596 if (LoadedVT == MVT::i64) {
597 if (TII->isValidAutoIncImm(LoadedVT, Val))
598 Opcode = Hexagon::POST_LDrid;
600 Opcode = Hexagon::LDrid;
601 } else if (LoadedVT == MVT::i32) {
602 if (TII->isValidAutoIncImm(LoadedVT, Val))
603 Opcode = Hexagon::POST_LDriw;
605 Opcode = Hexagon::LDriw;
606 } else if (LoadedVT == MVT::i16) {
607 if (TII->isValidAutoIncImm(LoadedVT, Val))
608 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
610 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
611 } else if (LoadedVT == MVT::i8) {
612 if (TII->isValidAutoIncImm(LoadedVT, Val))
613 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
615 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
617 llvm_unreachable("unknown memory type");
619 // For zero ext i64 loads, we need to add combine instructions.
620 if (LD->getValueType(0) == MVT::i64 &&
621 LD->getExtensionType() == ISD::ZEXTLOAD) {
622 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
624 if (LD->getValueType(0) == MVT::i64 &&
625 LD->getExtensionType() == ISD::SEXTLOAD) {
626 // Handle sign ext i64 loads.
627 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
629 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
630 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
631 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
633 MVT::i32, MVT::Other, Base,
634 TargetConstVal, Chain);
635 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
636 MemOp[0] = LD->getMemOperand();
637 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
638 const SDValue Froms[] = { SDValue(LD, 0),
642 const SDValue Tos[] = { SDValue(Result, 0),
646 ReplaceUses(Froms, Tos, 3);
649 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
650 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
651 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
653 MVT::Other, Base, TargetConst0,
655 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
656 Base, TargetConstVal,
657 SDValue(Result_1, 1));
658 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
659 MemOp[0] = LD->getMemOperand();
660 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
661 const SDValue Froms[] = { SDValue(LD, 0),
665 const SDValue Tos[] = { SDValue(Result_1, 0),
666 SDValue(Result_2, 0),
669 ReplaceUses(Froms, Tos, 3);
675 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
678 LoadSDNode *LD = cast<LoadSDNode>(N);
679 ISD::MemIndexedMode AM = LD->getAddressingMode();
681 // Handle indexed loads.
682 if (AM != ISD::UNINDEXED) {
683 result = SelectIndexedLoad(LD, dl);
685 result = SelectBaseOffsetLoad(LD, dl);
692 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
693 SDValue Chain = ST->getChain();
694 SDValue Base = ST->getBasePtr();
695 SDValue Offset = ST->getOffset();
696 SDValue Value = ST->getValue();
697 SDNode *OffsetNode = Offset.getNode();
698 // Get the constant value.
699 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
700 EVT StoredVT = ST->getMemoryVT();
702 // Offset value must be within representable range
703 // and must have correct alignment properties.
704 const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
705 TM.getSubtargetImpl()->getInstrInfo());
706 if (TII->isValidAutoIncImm(StoredVT, Val)) {
707 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
711 // Figure out the post inc version of opcode.
712 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
713 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
714 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
715 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
716 else llvm_unreachable("unknown memory type");
718 // Build post increment store.
719 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
721 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
722 MemOp[0] = ST->getMemOperand();
723 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
725 ReplaceUses(ST, Result);
726 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
730 // Note: Order of operands matches the def of instruction:
731 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
732 // and it differs for POST_ST* for instance.
733 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
737 // Figure out the opcode.
738 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
739 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
740 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
741 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
742 else llvm_unreachable("unknown memory type");
744 // Build regular store.
745 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
746 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
747 // Build splitted incriment instruction.
748 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
751 SDValue(Result_1, 0));
752 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
753 MemOp[0] = ST->getMemOperand();
754 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
756 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
757 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
762 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
764 SDValue Chain = ST->getChain();
765 SDNode* Const32 = ST->getBasePtr().getNode();
766 SDValue Value = ST->getValue();
769 // Try to lower stores of GlobalAdresses into indexed stores. Custom
770 // lowering for GlobalAddress nodes has already turned it into a
771 // CONST32. Avoid truncating stores for the moment. Post-inc stores
772 // do the same. Don't think there's a reason for it, so will file a
774 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
775 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
776 SDValue Base = Const32->getOperand(0);
777 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
778 EVT StoredVT = ST->getMemoryVT();
779 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
780 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
781 MVT PointerTy = getTargetLowering()->getPointerTy();
782 const GlobalValue* GV =
783 cast<GlobalAddressSDNode>(Base)->getGlobal();
785 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
786 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
790 // Figure out base + offset opcode
791 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
792 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
793 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
794 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
795 else llvm_unreachable("unknown memory type");
797 SDValue Ops[] = {SDValue(NewBase,0),
798 CurDAG->getTargetConstant(Offset,PointerTy),
800 // build indexed store
801 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
803 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
804 MemOp[0] = ST->getMemOperand();
805 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
806 ReplaceUses(ST, Result);
812 return SelectCode(ST);
816 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
818 StoreSDNode *ST = cast<StoreSDNode>(N);
819 ISD::MemIndexedMode AM = ST->getAddressingMode();
821 // Handle indexed stores.
822 if (AM != ISD::UNINDEXED) {
823 return SelectIndexedStore(ST, dl);
826 return SelectBaseOffsetStore(ST, dl);
829 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
833 // %conv.i = sext i32 %tmp1 to i64
834 // %conv2.i = sext i32 %add to i64
835 // %mul.i = mul nsw i64 %conv2.i, %conv.i
837 // --- match with the following ---
839 // %mul.i = mpy (%tmp1, %add)
842 if (N->getValueType(0) == MVT::i64) {
843 // Shifting a i64 signed multiply.
844 SDValue MulOp0 = N->getOperand(0);
845 SDValue MulOp1 = N->getOperand(1);
850 // Handle sign_extend and sextload.
851 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
852 SDValue Sext0 = MulOp0.getOperand(0);
853 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
854 return SelectCode(N);
858 } else if (MulOp0.getOpcode() == ISD::LOAD) {
859 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
860 if (LD->getMemoryVT() != MVT::i32 ||
861 LD->getExtensionType() != ISD::SEXTLOAD ||
862 LD->getAddressingMode() != ISD::UNINDEXED) {
863 return SelectCode(N);
866 SDValue Chain = LD->getChain();
867 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
868 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
870 LD->getBasePtr(), TargetConst0,
873 return SelectCode(N);
876 // Same goes for the second operand.
877 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
878 SDValue Sext1 = MulOp1.getOperand(0);
879 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
880 return SelectCode(N);
884 } else if (MulOp1.getOpcode() == ISD::LOAD) {
885 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
886 if (LD->getMemoryVT() != MVT::i32 ||
887 LD->getExtensionType() != ISD::SEXTLOAD ||
888 LD->getAddressingMode() != ISD::UNINDEXED) {
889 return SelectCode(N);
892 SDValue Chain = LD->getChain();
893 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
894 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
896 LD->getBasePtr(), TargetConst0,
899 return SelectCode(N);
902 // Generate a mpy instruction.
903 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
905 ReplaceUses(N, Result);
909 return SelectCode(N);
913 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
915 SDValue N0 = N->getOperand(0);
916 if (N0.getOpcode() == ISD::SETCC) {
917 SDValue N00 = N0.getOperand(0);
918 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
919 SDValue N000 = N00.getOperand(0);
920 SDValue N001 = N00.getOperand(1);
921 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
922 SDValue N01 = N0.getOperand(1);
923 SDValue N02 = N0.getOperand(2);
925 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
926 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
927 // IntRegs:i32:$src2)
928 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
929 // Pattern complexity = 9 cost = 1 size = 0.
930 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
931 SDValue N1 = N->getOperand(1);
933 SDValue N2 = N->getOperand(2);
935 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
936 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
937 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
939 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
941 SDValue(SextNode, 0),
943 ReplaceUses(N, Result);
949 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
950 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
951 // IntRegs:i32:$src2)
952 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
953 // Pattern complexity = 9 cost = 1 size = 0.
954 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
955 SDValue N1 = N->getOperand(1);
957 SDValue N2 = N->getOperand(2);
959 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
960 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
961 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
963 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
965 SDValue(SextNode, 0),
967 ReplaceUses(N, Result);
976 return SelectCode(N);
980 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
982 SDValue Shift = N->getOperand(0);
985 // %conv.i = sext i32 %tmp1 to i64
986 // %conv2.i = sext i32 %add to i64
987 // %mul.i = mul nsw i64 %conv2.i, %conv.i
988 // %shr5.i = lshr i64 %mul.i, 32
989 // %conv3.i = trunc i64 %shr5.i to i32
991 // --- match with the following ---
993 // %conv3.i = mpy (%tmp1, %add)
996 if (N->getValueType(0) == MVT::i32) {
998 if (Shift.getNode()->getValueType(0) == MVT::i64) {
999 // Trunc child is logical shift right.
1000 if (Shift.getOpcode() != ISD::SRL) {
1001 return SelectCode(N);
1004 SDValue ShiftOp0 = Shift.getOperand(0);
1005 SDValue ShiftOp1 = Shift.getOperand(1);
1007 // Shift by const 32
1008 if (ShiftOp1.getOpcode() != ISD::Constant) {
1009 return SelectCode(N);
1012 int32_t ShiftConst =
1013 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
1014 if (ShiftConst != 32) {
1015 return SelectCode(N);
1018 // Shifting a i64 signed multiply
1019 SDValue Mul = ShiftOp0;
1020 if (Mul.getOpcode() != ISD::MUL) {
1021 return SelectCode(N);
1024 SDValue MulOp0 = Mul.getOperand(0);
1025 SDValue MulOp1 = Mul.getOperand(1);
1030 // Handle sign_extend and sextload
1031 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
1032 SDValue Sext0 = MulOp0.getOperand(0);
1033 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
1034 return SelectCode(N);
1038 } else if (MulOp0.getOpcode() == ISD::LOAD) {
1039 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
1040 if (LD->getMemoryVT() != MVT::i32 ||
1041 LD->getExtensionType() != ISD::SEXTLOAD ||
1042 LD->getAddressingMode() != ISD::UNINDEXED) {
1043 return SelectCode(N);
1046 SDValue Chain = LD->getChain();
1047 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1048 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1051 TargetConst0, Chain), 0);
1053 return SelectCode(N);
1056 // Same goes for the second operand.
1057 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
1058 SDValue Sext1 = MulOp1.getOperand(0);
1059 if (Sext1.getNode()->getValueType(0) != MVT::i32)
1060 return SelectCode(N);
1063 } else if (MulOp1.getOpcode() == ISD::LOAD) {
1064 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
1065 if (LD->getMemoryVT() != MVT::i32 ||
1066 LD->getExtensionType() != ISD::SEXTLOAD ||
1067 LD->getAddressingMode() != ISD::UNINDEXED) {
1068 return SelectCode(N);
1071 SDValue Chain = LD->getChain();
1072 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1073 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1076 TargetConst0, Chain), 0);
1078 return SelectCode(N);
1081 // Generate a mpy instruction.
1082 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
1084 ReplaceUses(N, Result);
1089 return SelectCode(N);
1093 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
1095 if (N->getValueType(0) == MVT::i32) {
1096 SDValue Shl_0 = N->getOperand(0);
1097 SDValue Shl_1 = N->getOperand(1);
1099 if (Shl_1.getOpcode() == ISD::Constant) {
1100 if (Shl_0.getOpcode() == ISD::MUL) {
1101 SDValue Mul_0 = Shl_0.getOperand(0); // Val
1102 SDValue Mul_1 = Shl_0.getOperand(1); // Const
1103 // RHS of mul is const.
1104 if (Mul_1.getOpcode() == ISD::Constant) {
1106 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1108 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1109 int32_t ValConst = MulConst << ShlConst;
1110 SDValue Val = CurDAG->getTargetConstant(ValConst,
1112 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1113 if (isInt<9>(CN->getSExtValue())) {
1115 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
1116 MVT::i32, Mul_0, Val);
1117 ReplaceUses(N, Result);
1122 } else if (Shl_0.getOpcode() == ISD::SUB) {
1123 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1124 SDValue Sub_1 = Shl_0.getOperand(1); // Val
1125 if (Sub_0.getOpcode() == ISD::Constant) {
1127 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1128 if (SubConst == 0) {
1129 if (Sub_1.getOpcode() == ISD::SHL) {
1130 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1131 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1132 if (Shl2_1.getOpcode() == ISD::Constant) {
1134 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1136 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1137 int32_t ValConst = 1 << (ShlConst+Shl2Const);
1138 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1139 if (ConstantSDNode *CN =
1140 dyn_cast<ConstantSDNode>(Val.getNode()))
1141 if (isInt<9>(CN->getSExtValue())) {
1143 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
1145 ReplaceUses(N, Result);
1155 return SelectCode(N);
1160 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1161 // result of the intrinsic is predicate); convert the zero_extend to
1162 // transfer instruction.
1164 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1165 // converted into a MUX as predicate registers defined as 1 bit in the
1166 // compiler. Architecture defines them as 8-bit registers.
1167 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1169 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1171 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1172 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1174 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1175 if (doesIntrinsicReturnPredicate(ID)) {
1176 // Now we need to differentiate target data types.
1177 if (N->getValueType(0) == MVT::i64) {
1178 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1179 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1180 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1182 SDValue(IsIntrinsic, 0));
1183 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
1186 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
1187 MVT::i64, MVT::Other,
1188 SDValue(Result_2, 0),
1189 SDValue(Result_1, 0));
1190 ReplaceUses(N, Result_3);
1193 if (N->getValueType(0) == MVT::i32) {
1194 // Convert the zero_extend to Rs = Pd
1195 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1197 SDValue(IsIntrinsic, 0));
1198 ReplaceUses(N, RsPd);
1201 llvm_unreachable("Unexpected value type");
1204 return SelectCode(N);
1209 // Checking for intrinsics which have predicate registers as operand(s)
1210 // and lowering to the actual intrinsic.
1212 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1214 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1215 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
1217 // We are concerned with only those intrinsics that have predicate registers
1218 // as at least one of the operands.
1219 if (IntrinsicWithPred) {
1220 SmallVector<SDValue, 8> Ops;
1221 const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
1222 TM.getSubtargetImpl()->getInstrInfo());
1223 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
1224 const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
1226 // Iterate over all the operands of the intrinsics.
1227 // For PredRegs, do the transfer.
1228 // For Double/Int Regs, just preserve the value
1229 // For immediates, lower it.
1230 for (unsigned i = 1; i < N->getNumOperands(); ++i) {
1231 SDNode *Arg = N->getOperand(i).getNode();
1232 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF);
1234 if (RC == &Hexagon::IntRegsRegClass ||
1235 RC == &Hexagon::DoubleRegsRegClass) {
1236 Ops.push_back(SDValue(Arg, 0));
1237 } else if (RC == &Hexagon::PredRegsRegClass) {
1239 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1241 Ops.push_back(SDValue(PdRs,0));
1242 } else if (!RC && (dyn_cast<ConstantSDNode>(Arg) != nullptr)) {
1243 // This is immediate operand. Lower it here making sure that we DO have
1244 // const SDNode for immediate value.
1245 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
1246 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
1247 Ops.push_back(SDVal);
1249 llvm_unreachable("Unimplemented");
1252 EVT ReturnValueVT = N->getValueType(0);
1253 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
1254 ReturnValueVT, Ops);
1255 ReplaceUses(N, Result);
1258 return SelectCode(N);
1262 // Map floating point constant values.
1264 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1266 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1267 APFloat APF = CN->getValueAPF();
1268 if (N->getValueType(0) == MVT::f32) {
1269 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1270 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1272 else if (N->getValueType(0) == MVT::f64) {
1273 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1274 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1277 return SelectCode(N);
1282 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1284 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1286 if (N->getValueType(0) == MVT::i1) {
1288 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1290 // Create the IntReg = 1 node.
1292 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1293 CurDAG->getTargetConstant(0, MVT::i32));
1296 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1297 SDValue(IntRegTFR, 0));
1300 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
1304 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1305 SDValue(Pd, 0), SDValue(NotPd, 0));
1307 // We have just built:
1309 // Pd = xor(not(Pd), Pd)
1311 ReplaceUses(N, Result);
1316 return SelectCode(N);
1321 // Map add followed by a asr -> asr +=.
1323 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1325 if (N->getValueType(0) != MVT::i32) {
1326 return SelectCode(N);
1328 // Identify nodes of the form: add(asr(...)).
1329 SDNode* Src1 = N->getOperand(0).getNode();
1330 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1331 || Src1->getValueType(0) != MVT::i32) {
1332 return SelectCode(N);
1335 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1336 // Rd and Rd' are assigned to the same register
1337 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
1339 Src1->getOperand(0),
1340 Src1->getOperand(1));
1341 ReplaceUses(N, Result);
1347 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1348 if (N->isMachineOpcode()) {
1350 return nullptr; // Already selected.
1354 switch (N->getOpcode()) {
1356 return SelectConstant(N);
1358 case ISD::ConstantFP:
1359 return SelectConstantFP(N);
1362 return SelectAdd(N);
1365 return SelectSHL(N);
1368 return SelectLoad(N);
1371 return SelectStore(N);
1374 return SelectSelect(N);
1377 return SelectTruncate(N);
1380 return SelectMul(N);
1382 case ISD::ZERO_EXTEND:
1383 return SelectZeroExtend(N);
1385 case ISD::INTRINSIC_WO_CHAIN:
1386 return SelectIntrinsicWOChain(N);
1389 return SelectCode(N);
1394 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1395 // to define these instructions.
1397 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1399 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1400 Addr.getOpcode() == ISD::TargetGlobalAddress)
1401 return false; // Direct calls.
1403 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1404 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1405 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1409 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1414 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1416 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1417 Addr.getOpcode() == ISD::TargetGlobalAddress)
1418 return false; // Direct calls.
1420 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1421 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1422 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1423 return (IsS11_0_Offset(Offset.getNode()));
1426 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1427 return (IsS11_0_Offset(Offset.getNode()));
1431 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1433 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1434 Addr.getOpcode() == ISD::TargetGlobalAddress)
1435 return false; // Direct calls.
1437 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1438 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1439 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1440 return (IsS11_1_Offset(Offset.getNode()));
1443 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1444 return (IsS11_1_Offset(Offset.getNode()));
1448 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1450 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1451 Addr.getOpcode() == ISD::TargetGlobalAddress)
1452 return false; // Direct calls.
1454 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1455 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1456 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1457 return (IsS11_2_Offset(Offset.getNode()));
1460 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1461 return (IsS11_2_Offset(Offset.getNode()));
1465 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1467 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1468 Addr.getOpcode() == ISD::TargetGlobalAddress)
1469 return false; // Direct calls.
1471 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1472 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1473 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1474 return (IsU6_0_Offset(Offset.getNode()));
1477 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1478 return (IsU6_0_Offset(Offset.getNode()));
1482 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1484 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1485 Addr.getOpcode() == ISD::TargetGlobalAddress)
1486 return false; // Direct calls.
1488 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1489 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1490 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1491 return (IsU6_1_Offset(Offset.getNode()));
1494 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1495 return (IsU6_1_Offset(Offset.getNode()));
1499 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1501 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1502 Addr.getOpcode() == ISD::TargetGlobalAddress)
1503 return false; // Direct calls.
1505 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1506 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1507 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1508 return (IsU6_2_Offset(Offset.getNode()));
1511 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1512 return (IsU6_2_Offset(Offset.getNode()));
1516 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1519 if (Addr.getOpcode() != ISD::ADD) {
1520 return(SelectADDRriS11_2(Addr, Base, Offset));
1523 return SelectADDRriS11_2(Addr, Base, Offset);
1527 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1529 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1530 Addr.getOpcode() == ISD::TargetGlobalAddress)
1531 return false; // Direct calls.
1533 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1534 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1535 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1536 return (IsS11_3_Offset(Offset.getNode()));
1539 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1540 return (IsS11_3_Offset(Offset.getNode()));
1543 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1545 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1546 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1547 Addr.getOpcode() == ISD::TargetGlobalAddress)
1548 return false; // Direct calls.
1550 if (Addr.getOpcode() == ISD::ADD) {
1551 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1552 if (isInt<13>(CN->getSExtValue()))
1553 return false; // Let the reg+imm pattern catch this!
1554 R1 = Addr.getOperand(0);
1555 R2 = Addr.getOperand(1);
1565 // Handle generic address case. It is accessed from inlined asm =m constraints,
1566 // which could have any kind of pointer.
1567 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1568 SDValue &Base, SDValue &Offset) {
1569 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1570 Addr.getOpcode() == ISD::TargetGlobalAddress)
1571 return false; // Direct calls.
1573 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1574 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1575 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1579 if (Addr.getOpcode() == ISD::ADD) {
1580 Base = Addr.getOperand(0);
1581 Offset = Addr.getOperand(1);
1586 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1591 bool HexagonDAGToDAGISel::
1592 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1593 std::vector<SDValue> &OutOps) {
1596 switch (ConstraintCode) {
1597 case 'o': // Offsetable.
1598 case 'v': // Not offsetable.
1599 default: return true;
1600 case 'm': // Memory.
1601 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1606 OutOps.push_back(Op0);
1607 OutOps.push_back(Op1);
1611 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
1612 unsigned UseCount = 0;
1613 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
1617 return (UseCount <= 1);
1621 //===--------------------------------------------------------------------===//
1622 // Return 'true' if use count of the global address is below threshold.
1623 //===--------------------------------------------------------------------===//
1624 bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const {
1625 assert(N->getOpcode() == ISD::TargetGlobalAddress &&
1626 "Expecting a target global address");
1628 // Always try to fold the address.
1629 if (TM.getOptLevel() == CodeGenOpt::Aggressive)
1632 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
1633 DenseMap<const GlobalValue *, unsigned>::const_iterator GI =
1634 GlobalAddressUseCountMap.find(GA->getGlobal());
1636 if (GI == GlobalAddressUseCountMap.end())
1639 return GI->second <= MaxNumOfUsesForConstExtenders;
1642 //===--------------------------------------------------------------------===//
1643 // Return true if the non-GP-relative global address can be folded.
1644 //===--------------------------------------------------------------------===//
1645 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
1646 return foldGlobalAddressImpl(N, R, false);
1649 //===--------------------------------------------------------------------===//
1650 // Return true if the GP-relative global address can be folded.
1651 //===--------------------------------------------------------------------===//
1652 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
1653 return foldGlobalAddressImpl(N, R, true);
1656 //===--------------------------------------------------------------------===//
1657 // Fold offset of the global address if number of uses are below threshold.
1658 //===--------------------------------------------------------------------===//
1659 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
1660 bool ShouldLookForGP) {
1661 if (N.getOpcode() == ISD::ADD) {
1662 SDValue N0 = N.getOperand(0);
1663 SDValue N1 = N.getOperand(1);
1664 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
1665 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
1666 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
1667 GlobalAddressSDNode *GA =
1668 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
1671 (GA->getOpcode() == ISD::TargetGlobalAddress)) {
1672 if ((N0.getOpcode() == HexagonISD::CONST32) &&
1673 !hasNumUsesBelowThresGA(GA))
1675 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
1679 (uint64_t)Const->getSExtValue());