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 const HexagonInstrInfo *TII;
54 DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap;
56 explicit HexagonDAGToDAGISel(const HexagonTargetMachine &targetmachine,
57 CodeGenOpt::Level OptLevel)
58 : SelectionDAGISel(targetmachine, OptLevel),
59 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
61 TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {
62 initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
64 bool hasNumUsesBelowThresGA(SDNode *N) const;
66 SDNode *Select(SDNode *N);
68 // Complex Pattern Selectors.
69 inline bool foldGlobalAddress(SDValue &N, SDValue &R);
70 inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
71 bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
72 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
73 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
74 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
75 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
76 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
77 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
78 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
79 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
80 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
81 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
83 virtual const char *getPassName() const {
84 return "Hexagon DAG->DAG Pattern Instruction Selection";
87 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
88 /// inline asm expressions.
89 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
91 std::vector<SDValue> &OutOps);
92 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
94 SDNode *SelectLoad(SDNode *N);
95 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl);
96 SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl);
97 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
99 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
101 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl);
102 SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl);
103 SDNode *SelectStore(SDNode *N);
104 SDNode *SelectSHL(SDNode *N);
105 SDNode *SelectSelect(SDNode *N);
106 SDNode *SelectTruncate(SDNode *N);
107 SDNode *SelectMul(SDNode *N);
108 SDNode *SelectZeroExtend(SDNode *N);
109 SDNode *SelectIntrinsicWOChain(SDNode *N);
110 SDNode *SelectIntrinsicWChain(SDNode *N);
111 SDNode *SelectConstant(SDNode *N);
112 SDNode *SelectConstantFP(SDNode *N);
113 SDNode *SelectAdd(SDNode *N);
114 bool isConstExtProfitable(SDNode *N) const;
116 // XformMskToBitPosU5Imm - Returns the bit position which
117 // the single bit 32 bit mask represents.
118 // Used in Clr and Set bit immediate memops.
119 SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
121 bitPos = Log2_32(Imm);
122 assert(bitPos >= 0 && bitPos < 32 &&
123 "Constant out of range for 32 BitPos Memops");
124 return CurDAG->getTargetConstant(bitPos, MVT::i32);
127 // XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
128 // mask represents. Used in Clr and Set bit immediate memops.
129 SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
130 return XformMskToBitPosU5Imm(Imm);
133 // XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
134 // mask represents. Used in Clr and Set bit immediate memops.
135 SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
136 return XformMskToBitPosU5Imm(Imm);
139 // Return true if there is exactly one bit set in V, i.e., if V is one of the
140 // following integers: 2^0, 2^1, ..., 2^31.
141 bool ImmIsSingleBit(uint32_t v) const {
142 uint32_t c = CountPopulation_64(v);
143 // Only return true if we counted 1 bit.
147 // XformM5ToU5Imm - Return a target constant with the specified value, of type
148 // i32 where the negative literal is transformed into a positive literal for
150 inline SDValue XformM5ToU5Imm(signed Imm) {
151 assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
152 return CurDAG->getTargetConstant( - Imm, MVT::i32);
156 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
157 // [1..128], used in cmpb.gtu instructions.
158 inline SDValue XformU7ToU7M1Imm(signed Imm) {
159 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
160 return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
163 // XformS8ToS8M1Imm - Return a target constant decremented by 1.
164 inline SDValue XformSToSM1Imm(signed Imm) {
165 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
168 // XformU8ToU8M1Imm - Return a target constant decremented by 1.
169 inline SDValue XformUToUM1Imm(unsigned Imm) {
170 assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
171 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
174 // Include the pieces autogenerated from the target description.
175 #include "HexagonGenDAGISel.inc"
177 } // end anonymous namespace
180 /// createHexagonISelDag - This pass converts a legalized DAG into a
181 /// Hexagon-specific DAG, ready for instruction scheduling.
183 FunctionPass *llvm::createHexagonISelDag(const HexagonTargetMachine &TM,
184 CodeGenOpt::Level OptLevel) {
185 return new HexagonDAGToDAGISel(TM, OptLevel);
188 static void initializePassOnce(PassRegistry &Registry) {
189 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
190 PassInfo *PI = new PassInfo(Name, "hexagon-isel",
191 &SelectionDAGISel::ID, 0, false, false);
192 Registry.registerPass(*PI, true);
195 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
196 CALL_ONCE_INITIALIZATION(initializePassOnce)
200 static bool IsS11_0_Offset(SDNode * S) {
201 ConstantSDNode *N = cast<ConstantSDNode>(S);
203 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
205 int64_t v = (int64_t)N->getSExtValue();
210 static bool IsS11_1_Offset(SDNode * S) {
211 ConstantSDNode *N = cast<ConstantSDNode>(S);
213 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
215 int64_t v = (int64_t)N->getSExtValue();
216 return isShiftedInt<11,1>(v);
220 static bool IsS11_2_Offset(SDNode * S) {
221 ConstantSDNode *N = cast<ConstantSDNode>(S);
223 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
225 int64_t v = (int64_t)N->getSExtValue();
226 return isShiftedInt<11,2>(v);
230 static bool IsS11_3_Offset(SDNode * S) {
231 ConstantSDNode *N = cast<ConstantSDNode>(S);
233 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
235 int64_t v = (int64_t)N->getSExtValue();
236 return isShiftedInt<11,3>(v);
240 static bool IsU6_0_Offset(SDNode * S) {
241 ConstantSDNode *N = cast<ConstantSDNode>(S);
243 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
245 int64_t v = (int64_t)N->getSExtValue();
250 static bool IsU6_1_Offset(SDNode * S) {
251 ConstantSDNode *N = cast<ConstantSDNode>(S);
253 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
255 int64_t v = (int64_t)N->getSExtValue();
256 return isShiftedUInt<6,1>(v);
260 static bool IsU6_2_Offset(SDNode * S) {
261 ConstantSDNode *N = cast<ConstantSDNode>(S);
263 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
265 int64_t v = (int64_t)N->getSExtValue();
266 return isShiftedUInt<6,2>(v);
270 // Intrinsics that return a a predicate.
271 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
276 case Intrinsic::hexagon_C2_cmpeq:
277 case Intrinsic::hexagon_C2_cmpgt:
278 case Intrinsic::hexagon_C2_cmpgtu:
279 case Intrinsic::hexagon_C2_cmpgtup:
280 case Intrinsic::hexagon_C2_cmpgtp:
281 case Intrinsic::hexagon_C2_cmpeqp:
282 case Intrinsic::hexagon_C2_bitsset:
283 case Intrinsic::hexagon_C2_bitsclr:
284 case Intrinsic::hexagon_C2_cmpeqi:
285 case Intrinsic::hexagon_C2_cmpgti:
286 case Intrinsic::hexagon_C2_cmpgtui:
287 case Intrinsic::hexagon_C2_cmpgei:
288 case Intrinsic::hexagon_C2_cmpgeui:
289 case Intrinsic::hexagon_C2_cmplt:
290 case Intrinsic::hexagon_C2_cmpltu:
291 case Intrinsic::hexagon_C2_bitsclri:
292 case Intrinsic::hexagon_C2_and:
293 case Intrinsic::hexagon_C2_or:
294 case Intrinsic::hexagon_C2_xor:
295 case Intrinsic::hexagon_C2_andn:
296 case Intrinsic::hexagon_C2_not:
297 case Intrinsic::hexagon_C2_orn:
298 case Intrinsic::hexagon_C2_pxfer_map:
299 case Intrinsic::hexagon_C2_any8:
300 case Intrinsic::hexagon_C2_all8:
301 case Intrinsic::hexagon_A2_vcmpbeq:
302 case Intrinsic::hexagon_A2_vcmpbgtu:
303 case Intrinsic::hexagon_A2_vcmpheq:
304 case Intrinsic::hexagon_A2_vcmphgt:
305 case Intrinsic::hexagon_A2_vcmphgtu:
306 case Intrinsic::hexagon_A2_vcmpweq:
307 case Intrinsic::hexagon_A2_vcmpwgt:
308 case Intrinsic::hexagon_A2_vcmpwgtu:
309 case Intrinsic::hexagon_C2_tfrrp:
310 case Intrinsic::hexagon_S2_tstbit_i:
311 case Intrinsic::hexagon_S2_tstbit_r:
317 // Intrinsics that have predicate operands.
318 static unsigned doesIntrinsicContainPredicate(unsigned ID)
323 case Intrinsic::hexagon_C2_tfrpr:
324 return Hexagon::TFR_RsPd;
325 case Intrinsic::hexagon_C2_and:
326 return Hexagon::AND_pp;
327 case Intrinsic::hexagon_C2_xor:
328 return Hexagon::XOR_pp;
329 case Intrinsic::hexagon_C2_or:
330 return Hexagon::OR_pp;
331 case Intrinsic::hexagon_C2_not:
332 return Hexagon::NOT_p;
333 case Intrinsic::hexagon_C2_any8:
334 return Hexagon::ANY_pp;
335 case Intrinsic::hexagon_C2_all8:
336 return Hexagon::ALL_pp;
337 case Intrinsic::hexagon_C2_vitpack:
338 return Hexagon::VITPACK_pp;
339 case Intrinsic::hexagon_C2_mask:
340 return Hexagon::MASK_p;
341 case Intrinsic::hexagon_C2_mux:
342 return Hexagon::MUX_rr;
344 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
345 // that's how it's mapped in q6protos.h.
346 case Intrinsic::hexagon_C2_muxir:
347 return Hexagon::MUX_ri;
349 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
350 // that's how it's mapped in q6protos.h.
351 case Intrinsic::hexagon_C2_muxri:
352 return Hexagon::MUX_ir;
354 case Intrinsic::hexagon_C2_muxii:
355 return Hexagon::MUX_ii;
356 case Intrinsic::hexagon_C2_vmux:
357 return Hexagon::VMUX_prr64;
358 case Intrinsic::hexagon_S2_valignrb:
359 return Hexagon::VALIGN_rrp;
360 case Intrinsic::hexagon_S2_vsplicerb:
361 return Hexagon::VSPLICE_rrp;
366 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
367 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
370 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
373 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
376 if (MemType == MVT::i8 && isInt<11>(Offset)) {
384 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
385 // lowering for GlobalAddress nodes has already turned it into a
388 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) {
389 SDValue Chain = LD->getChain();
390 SDNode* Const32 = LD->getBasePtr().getNode();
393 if (Const32->getOpcode() == HexagonISD::CONST32 &&
394 ISD::isNormalLoad(LD)) {
395 SDValue Base = Const32->getOperand(0);
396 EVT LoadedVT = LD->getMemoryVT();
397 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
398 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
399 MVT PointerTy = TLI.getPointerTy();
400 const GlobalValue* GV =
401 cast<GlobalAddressSDNode>(Base)->getGlobal();
403 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
404 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
407 // Figure out base + offset opcode
408 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
409 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
410 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
411 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
412 else llvm_unreachable("unknown memory type");
414 // Build indexed load.
415 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
416 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
422 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
423 MemOp[0] = LD->getMemOperand();
424 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
425 ReplaceUses(LD, Result);
430 return SelectCode(LD);
434 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
438 SDValue Chain = LD->getChain();
439 EVT LoadedVT = LD->getMemoryVT();
440 SDValue Base = LD->getBasePtr();
441 SDValue Offset = LD->getOffset();
442 SDNode *OffsetNode = Offset.getNode();
443 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
444 SDValue N1 = LD->getOperand(1);
447 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
448 N1.getNode()->getValueType(0) == MVT::i32) {
449 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
450 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
451 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
452 MVT::Other, Base, TargetConst,
454 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
455 SDValue(Result_1, 0));
456 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
457 MemOp[0] = LD->getMemOperand();
458 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
459 const SDValue Froms[] = { SDValue(LD, 0),
463 const SDValue Tos[] = { SDValue(Result_2, 0),
464 SDValue(Result_1, 1),
467 ReplaceUses(Froms, Tos, 3);
470 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
471 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
472 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
473 MVT::Other, Base, TargetConst0,
475 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
476 MVT::i64, SDValue(Result_1, 0));
477 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
478 MVT::i32, Base, TargetConstVal,
479 SDValue(Result_1, 1));
480 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
481 MemOp[0] = LD->getMemOperand();
482 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
483 const SDValue Froms[] = { SDValue(LD, 0),
487 const SDValue Tos[] = { SDValue(Result_2, 0),
488 SDValue(Result_3, 0),
491 ReplaceUses(Froms, Tos, 3);
494 return SelectCode(LD);
498 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
502 SDValue Chain = LD->getChain();
503 EVT LoadedVT = LD->getMemoryVT();
504 SDValue Base = LD->getBasePtr();
505 SDValue Offset = LD->getOffset();
506 SDNode *OffsetNode = Offset.getNode();
507 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
508 SDValue N1 = LD->getOperand(1);
511 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
512 N1.getNode()->getValueType(0) == MVT::i32) {
513 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
514 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
515 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
516 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
517 MVT::i32, MVT::Other, Base,
518 TargetConstVal, Chain);
519 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
521 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
522 MVT::i64, MVT::Other,
524 SDValue(Result_1,0));
525 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
526 MemOp[0] = LD->getMemOperand();
527 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
528 const SDValue Froms[] = { SDValue(LD, 0),
532 const SDValue Tos[] = { SDValue(Result_3, 0),
533 SDValue(Result_1, 1),
536 ReplaceUses(Froms, Tos, 3);
540 // Generate an indirect load.
541 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
542 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
543 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
545 Base, TargetConst0, Chain);
546 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
548 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
549 MVT::i64, MVT::Other,
551 SDValue(Result_1,0));
552 // Add offset to base.
553 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
554 Base, TargetConstVal,
555 SDValue(Result_1, 1));
556 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
557 MemOp[0] = LD->getMemOperand();
558 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
559 const SDValue Froms[] = { SDValue(LD, 0),
563 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
564 SDValue(Result_4, 0), // New address.
567 ReplaceUses(Froms, Tos, 3);
571 return SelectCode(LD);
575 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
576 SDValue Chain = LD->getChain();
577 SDValue Base = LD->getBasePtr();
578 SDValue Offset = LD->getOffset();
579 SDNode *OffsetNode = Offset.getNode();
580 // Get the constant value.
581 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
582 EVT LoadedVT = LD->getMemoryVT();
585 // Check for zero ext loads.
586 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
588 // Figure out the opcode.
589 if (LoadedVT == MVT::i64) {
590 if (TII->isValidAutoIncImm(LoadedVT, Val))
591 Opcode = Hexagon::POST_LDrid;
593 Opcode = Hexagon::LDrid;
594 } else if (LoadedVT == MVT::i32) {
595 if (TII->isValidAutoIncImm(LoadedVT, Val))
596 Opcode = Hexagon::POST_LDriw;
598 Opcode = Hexagon::LDriw;
599 } else if (LoadedVT == MVT::i16) {
600 if (TII->isValidAutoIncImm(LoadedVT, Val))
601 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
603 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
604 } else if (LoadedVT == MVT::i8) {
605 if (TII->isValidAutoIncImm(LoadedVT, Val))
606 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
608 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
610 llvm_unreachable("unknown memory type");
612 // For zero ext i64 loads, we need to add combine instructions.
613 if (LD->getValueType(0) == MVT::i64 &&
614 LD->getExtensionType() == ISD::ZEXTLOAD) {
615 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
617 if (LD->getValueType(0) == MVT::i64 &&
618 LD->getExtensionType() == ISD::SEXTLOAD) {
619 // Handle sign ext i64 loads.
620 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
622 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
623 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
624 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
626 MVT::i32, MVT::Other, Base,
627 TargetConstVal, Chain);
628 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
629 MemOp[0] = LD->getMemOperand();
630 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
631 const SDValue Froms[] = { SDValue(LD, 0),
635 const SDValue Tos[] = { SDValue(Result, 0),
639 ReplaceUses(Froms, Tos, 3);
642 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
643 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
644 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
646 MVT::Other, Base, TargetConst0,
648 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
649 Base, TargetConstVal,
650 SDValue(Result_1, 1));
651 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
652 MemOp[0] = LD->getMemOperand();
653 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
654 const SDValue Froms[] = { SDValue(LD, 0),
658 const SDValue Tos[] = { SDValue(Result_1, 0),
659 SDValue(Result_2, 0),
662 ReplaceUses(Froms, Tos, 3);
668 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
671 LoadSDNode *LD = cast<LoadSDNode>(N);
672 ISD::MemIndexedMode AM = LD->getAddressingMode();
674 // Handle indexed loads.
675 if (AM != ISD::UNINDEXED) {
676 result = SelectIndexedLoad(LD, dl);
678 result = SelectBaseOffsetLoad(LD, dl);
685 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
686 SDValue Chain = ST->getChain();
687 SDValue Base = ST->getBasePtr();
688 SDValue Offset = ST->getOffset();
689 SDValue Value = ST->getValue();
690 SDNode *OffsetNode = Offset.getNode();
691 // Get the constant value.
692 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
693 EVT StoredVT = ST->getMemoryVT();
695 // Offset value must be within representable range
696 // and must have correct alignment properties.
697 if (TII->isValidAutoIncImm(StoredVT, Val)) {
698 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
702 // Figure out the post inc version of opcode.
703 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
704 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
705 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
706 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
707 else llvm_unreachable("unknown memory type");
709 // Build post increment store.
710 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
712 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
713 MemOp[0] = ST->getMemOperand();
714 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
716 ReplaceUses(ST, Result);
717 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
721 // Note: Order of operands matches the def of instruction:
722 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
723 // and it differs for POST_ST* for instance.
724 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
728 // Figure out the opcode.
729 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
730 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
731 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
732 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
733 else llvm_unreachable("unknown memory type");
735 // Build regular store.
736 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
737 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
738 // Build splitted incriment instruction.
739 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
742 SDValue(Result_1, 0));
743 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
744 MemOp[0] = ST->getMemOperand();
745 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
747 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
748 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
753 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
755 SDValue Chain = ST->getChain();
756 SDNode* Const32 = ST->getBasePtr().getNode();
757 SDValue Value = ST->getValue();
760 // Try to lower stores of GlobalAdresses into indexed stores. Custom
761 // lowering for GlobalAddress nodes has already turned it into a
762 // CONST32. Avoid truncating stores for the moment. Post-inc stores
763 // do the same. Don't think there's a reason for it, so will file a
765 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
766 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
767 SDValue Base = Const32->getOperand(0);
768 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
769 EVT StoredVT = ST->getMemoryVT();
770 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
771 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
772 MVT PointerTy = TLI.getPointerTy();
773 const GlobalValue* GV =
774 cast<GlobalAddressSDNode>(Base)->getGlobal();
776 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
777 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
781 // Figure out base + offset opcode
782 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
783 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
784 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
785 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
786 else llvm_unreachable("unknown memory type");
788 SDValue Ops[] = {SDValue(NewBase,0),
789 CurDAG->getTargetConstant(Offset,PointerTy),
791 // build indexed store
792 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
794 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
795 MemOp[0] = ST->getMemOperand();
796 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
797 ReplaceUses(ST, Result);
803 return SelectCode(ST);
807 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
809 StoreSDNode *ST = cast<StoreSDNode>(N);
810 ISD::MemIndexedMode AM = ST->getAddressingMode();
812 // Handle indexed stores.
813 if (AM != ISD::UNINDEXED) {
814 return SelectIndexedStore(ST, dl);
817 return SelectBaseOffsetStore(ST, dl);
820 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
824 // %conv.i = sext i32 %tmp1 to i64
825 // %conv2.i = sext i32 %add to i64
826 // %mul.i = mul nsw i64 %conv2.i, %conv.i
828 // --- match with the following ---
830 // %mul.i = mpy (%tmp1, %add)
833 if (N->getValueType(0) == MVT::i64) {
834 // Shifting a i64 signed multiply.
835 SDValue MulOp0 = N->getOperand(0);
836 SDValue MulOp1 = N->getOperand(1);
841 // Handle sign_extend and sextload.
842 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
843 SDValue Sext0 = MulOp0.getOperand(0);
844 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
845 return SelectCode(N);
849 } else if (MulOp0.getOpcode() == ISD::LOAD) {
850 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
851 if (LD->getMemoryVT() != MVT::i32 ||
852 LD->getExtensionType() != ISD::SEXTLOAD ||
853 LD->getAddressingMode() != ISD::UNINDEXED) {
854 return SelectCode(N);
857 SDValue Chain = LD->getChain();
858 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
859 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
861 LD->getBasePtr(), TargetConst0,
864 return SelectCode(N);
867 // Same goes for the second operand.
868 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
869 SDValue Sext1 = MulOp1.getOperand(0);
870 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
871 return SelectCode(N);
875 } else if (MulOp1.getOpcode() == ISD::LOAD) {
876 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
877 if (LD->getMemoryVT() != MVT::i32 ||
878 LD->getExtensionType() != ISD::SEXTLOAD ||
879 LD->getAddressingMode() != ISD::UNINDEXED) {
880 return SelectCode(N);
883 SDValue Chain = LD->getChain();
884 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
885 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
887 LD->getBasePtr(), TargetConst0,
890 return SelectCode(N);
893 // Generate a mpy instruction.
894 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
896 ReplaceUses(N, Result);
900 return SelectCode(N);
904 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
906 SDValue N0 = N->getOperand(0);
907 if (N0.getOpcode() == ISD::SETCC) {
908 SDValue N00 = N0.getOperand(0);
909 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
910 SDValue N000 = N00.getOperand(0);
911 SDValue N001 = N00.getOperand(1);
912 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
913 SDValue N01 = N0.getOperand(1);
914 SDValue N02 = N0.getOperand(2);
916 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
917 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
918 // IntRegs:i32:$src2)
919 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
920 // Pattern complexity = 9 cost = 1 size = 0.
921 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
922 SDValue N1 = N->getOperand(1);
924 SDValue N2 = N->getOperand(2);
926 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
927 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
928 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
930 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
932 SDValue(SextNode, 0),
934 ReplaceUses(N, Result);
940 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
941 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
942 // IntRegs:i32:$src2)
943 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
944 // Pattern complexity = 9 cost = 1 size = 0.
945 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
946 SDValue N1 = N->getOperand(1);
948 SDValue N2 = N->getOperand(2);
950 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
951 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
952 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
954 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
956 SDValue(SextNode, 0),
958 ReplaceUses(N, Result);
967 return SelectCode(N);
971 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
973 SDValue Shift = N->getOperand(0);
976 // %conv.i = sext i32 %tmp1 to i64
977 // %conv2.i = sext i32 %add to i64
978 // %mul.i = mul nsw i64 %conv2.i, %conv.i
979 // %shr5.i = lshr i64 %mul.i, 32
980 // %conv3.i = trunc i64 %shr5.i to i32
982 // --- match with the following ---
984 // %conv3.i = mpy (%tmp1, %add)
987 if (N->getValueType(0) == MVT::i32) {
989 if (Shift.getNode()->getValueType(0) == MVT::i64) {
990 // Trunc child is logical shift right.
991 if (Shift.getOpcode() != ISD::SRL) {
992 return SelectCode(N);
995 SDValue ShiftOp0 = Shift.getOperand(0);
996 SDValue ShiftOp1 = Shift.getOperand(1);
999 if (ShiftOp1.getOpcode() != ISD::Constant) {
1000 return SelectCode(N);
1003 int32_t ShiftConst =
1004 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
1005 if (ShiftConst != 32) {
1006 return SelectCode(N);
1009 // Shifting a i64 signed multiply
1010 SDValue Mul = ShiftOp0;
1011 if (Mul.getOpcode() != ISD::MUL) {
1012 return SelectCode(N);
1015 SDValue MulOp0 = Mul.getOperand(0);
1016 SDValue MulOp1 = Mul.getOperand(1);
1021 // Handle sign_extend and sextload
1022 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
1023 SDValue Sext0 = MulOp0.getOperand(0);
1024 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
1025 return SelectCode(N);
1029 } else if (MulOp0.getOpcode() == ISD::LOAD) {
1030 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
1031 if (LD->getMemoryVT() != MVT::i32 ||
1032 LD->getExtensionType() != ISD::SEXTLOAD ||
1033 LD->getAddressingMode() != ISD::UNINDEXED) {
1034 return SelectCode(N);
1037 SDValue Chain = LD->getChain();
1038 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1039 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1042 TargetConst0, Chain), 0);
1044 return SelectCode(N);
1047 // Same goes for the second operand.
1048 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
1049 SDValue Sext1 = MulOp1.getOperand(0);
1050 if (Sext1.getNode()->getValueType(0) != MVT::i32)
1051 return SelectCode(N);
1054 } else if (MulOp1.getOpcode() == ISD::LOAD) {
1055 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
1056 if (LD->getMemoryVT() != MVT::i32 ||
1057 LD->getExtensionType() != ISD::SEXTLOAD ||
1058 LD->getAddressingMode() != ISD::UNINDEXED) {
1059 return SelectCode(N);
1062 SDValue Chain = LD->getChain();
1063 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1064 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1067 TargetConst0, Chain), 0);
1069 return SelectCode(N);
1072 // Generate a mpy instruction.
1073 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
1075 ReplaceUses(N, Result);
1080 return SelectCode(N);
1084 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
1086 if (N->getValueType(0) == MVT::i32) {
1087 SDValue Shl_0 = N->getOperand(0);
1088 SDValue Shl_1 = N->getOperand(1);
1090 if (Shl_1.getOpcode() == ISD::Constant) {
1091 if (Shl_0.getOpcode() == ISD::MUL) {
1092 SDValue Mul_0 = Shl_0.getOperand(0); // Val
1093 SDValue Mul_1 = Shl_0.getOperand(1); // Const
1094 // RHS of mul is const.
1095 if (Mul_1.getOpcode() == ISD::Constant) {
1097 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1099 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1100 int32_t ValConst = MulConst << ShlConst;
1101 SDValue Val = CurDAG->getTargetConstant(ValConst,
1103 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1104 if (isInt<9>(CN->getSExtValue())) {
1106 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
1107 MVT::i32, Mul_0, Val);
1108 ReplaceUses(N, Result);
1113 } else if (Shl_0.getOpcode() == ISD::SUB) {
1114 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1115 SDValue Sub_1 = Shl_0.getOperand(1); // Val
1116 if (Sub_0.getOpcode() == ISD::Constant) {
1118 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1119 if (SubConst == 0) {
1120 if (Sub_1.getOpcode() == ISD::SHL) {
1121 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1122 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1123 if (Shl2_1.getOpcode() == ISD::Constant) {
1125 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1127 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1128 int32_t ValConst = 1 << (ShlConst+Shl2Const);
1129 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1130 if (ConstantSDNode *CN =
1131 dyn_cast<ConstantSDNode>(Val.getNode()))
1132 if (isInt<9>(CN->getSExtValue())) {
1134 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
1136 ReplaceUses(N, Result);
1146 return SelectCode(N);
1151 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1152 // result of the intrinsic is predicate); convert the zero_extend to
1153 // transfer instruction.
1155 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1156 // converted into a MUX as predicate registers defined as 1 bit in the
1157 // compiler. Architecture defines them as 8-bit registers.
1158 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1160 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1162 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1163 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1165 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1166 if (doesIntrinsicReturnPredicate(ID)) {
1167 // Now we need to differentiate target data types.
1168 if (N->getValueType(0) == MVT::i64) {
1169 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1170 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1171 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1173 SDValue(IsIntrinsic, 0));
1174 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
1177 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
1178 MVT::i64, MVT::Other,
1179 SDValue(Result_2, 0),
1180 SDValue(Result_1, 0));
1181 ReplaceUses(N, Result_3);
1184 if (N->getValueType(0) == MVT::i32) {
1185 // Convert the zero_extend to Rs = Pd
1186 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1188 SDValue(IsIntrinsic, 0));
1189 ReplaceUses(N, RsPd);
1192 llvm_unreachable("Unexpected value type");
1195 return SelectCode(N);
1200 // Checking for intrinsics which have predicate registers as operand(s)
1201 // and lowering to the actual intrinsic.
1203 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1205 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1206 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
1208 // We are concerned with only those intrinsics that have predicate registers
1209 // as at least one of the operands.
1210 if (IntrinsicWithPred) {
1211 SmallVector<SDValue, 8> Ops;
1212 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
1213 const TargetRegisterInfo *TRI = TM.getRegisterInfo();
1215 // Iterate over all the operands of the intrinsics.
1216 // For PredRegs, do the transfer.
1217 // For Double/Int Regs, just preserve the value
1218 // For immediates, lower it.
1219 for (unsigned i = 1; i < N->getNumOperands(); ++i) {
1220 SDNode *Arg = N->getOperand(i).getNode();
1221 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF);
1223 if (RC == &Hexagon::IntRegsRegClass ||
1224 RC == &Hexagon::DoubleRegsRegClass) {
1225 Ops.push_back(SDValue(Arg, 0));
1226 } else if (RC == &Hexagon::PredRegsRegClass) {
1228 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1230 Ops.push_back(SDValue(PdRs,0));
1231 } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
1232 // This is immediate operand. Lower it here making sure that we DO have
1233 // const SDNode for immediate value.
1234 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
1235 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
1236 Ops.push_back(SDVal);
1238 llvm_unreachable("Unimplemented");
1241 EVT ReturnValueVT = N->getValueType(0);
1242 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
1243 ReturnValueVT, Ops);
1244 ReplaceUses(N, Result);
1247 return SelectCode(N);
1251 // Map floating point constant values.
1253 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1255 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1256 APFloat APF = CN->getValueAPF();
1257 if (N->getValueType(0) == MVT::f32) {
1258 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1259 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1261 else if (N->getValueType(0) == MVT::f64) {
1262 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1263 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1266 return SelectCode(N);
1271 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1273 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1275 if (N->getValueType(0) == MVT::i1) {
1277 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1279 // Create the IntReg = 1 node.
1281 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1282 CurDAG->getTargetConstant(0, MVT::i32));
1285 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1286 SDValue(IntRegTFR, 0));
1289 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
1293 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1294 SDValue(Pd, 0), SDValue(NotPd, 0));
1296 // We have just built:
1298 // Pd = xor(not(Pd), Pd)
1300 ReplaceUses(N, Result);
1305 return SelectCode(N);
1310 // Map add followed by a asr -> asr +=.
1312 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1314 if (N->getValueType(0) != MVT::i32) {
1315 return SelectCode(N);
1317 // Identify nodes of the form: add(asr(...)).
1318 SDNode* Src1 = N->getOperand(0).getNode();
1319 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1320 || Src1->getValueType(0) != MVT::i32) {
1321 return SelectCode(N);
1324 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1325 // Rd and Rd' are assigned to the same register
1326 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
1328 Src1->getOperand(0),
1329 Src1->getOperand(1));
1330 ReplaceUses(N, Result);
1336 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1337 if (N->isMachineOpcode())
1338 return NULL; // Already selected.
1341 switch (N->getOpcode()) {
1343 return SelectConstant(N);
1345 case ISD::ConstantFP:
1346 return SelectConstantFP(N);
1349 return SelectAdd(N);
1352 return SelectSHL(N);
1355 return SelectLoad(N);
1358 return SelectStore(N);
1361 return SelectSelect(N);
1364 return SelectTruncate(N);
1367 return SelectMul(N);
1369 case ISD::ZERO_EXTEND:
1370 return SelectZeroExtend(N);
1372 case ISD::INTRINSIC_WO_CHAIN:
1373 return SelectIntrinsicWOChain(N);
1376 return SelectCode(N);
1381 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1382 // to define these instructions.
1384 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1386 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1387 Addr.getOpcode() == ISD::TargetGlobalAddress)
1388 return false; // Direct calls.
1390 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1391 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1392 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1396 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1401 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1403 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1404 Addr.getOpcode() == ISD::TargetGlobalAddress)
1405 return false; // Direct calls.
1407 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1408 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1409 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1410 return (IsS11_0_Offset(Offset.getNode()));
1413 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1414 return (IsS11_0_Offset(Offset.getNode()));
1418 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1420 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1421 Addr.getOpcode() == ISD::TargetGlobalAddress)
1422 return false; // Direct calls.
1424 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1425 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1426 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1427 return (IsS11_1_Offset(Offset.getNode()));
1430 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1431 return (IsS11_1_Offset(Offset.getNode()));
1435 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1437 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1438 Addr.getOpcode() == ISD::TargetGlobalAddress)
1439 return false; // Direct calls.
1441 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1442 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1443 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1444 return (IsS11_2_Offset(Offset.getNode()));
1447 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1448 return (IsS11_2_Offset(Offset.getNode()));
1452 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1454 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1455 Addr.getOpcode() == ISD::TargetGlobalAddress)
1456 return false; // Direct calls.
1458 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1459 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1460 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1461 return (IsU6_0_Offset(Offset.getNode()));
1464 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1465 return (IsU6_0_Offset(Offset.getNode()));
1469 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1471 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1472 Addr.getOpcode() == ISD::TargetGlobalAddress)
1473 return false; // Direct calls.
1475 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1476 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1477 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1478 return (IsU6_1_Offset(Offset.getNode()));
1481 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1482 return (IsU6_1_Offset(Offset.getNode()));
1486 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1488 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1489 Addr.getOpcode() == ISD::TargetGlobalAddress)
1490 return false; // Direct calls.
1492 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1493 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1494 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1495 return (IsU6_2_Offset(Offset.getNode()));
1498 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1499 return (IsU6_2_Offset(Offset.getNode()));
1503 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1506 if (Addr.getOpcode() != ISD::ADD) {
1507 return(SelectADDRriS11_2(Addr, Base, Offset));
1510 return SelectADDRriS11_2(Addr, Base, Offset);
1514 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1516 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1517 Addr.getOpcode() == ISD::TargetGlobalAddress)
1518 return false; // Direct calls.
1520 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1521 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1522 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1523 return (IsS11_3_Offset(Offset.getNode()));
1526 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1527 return (IsS11_3_Offset(Offset.getNode()));
1530 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1532 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1533 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1534 Addr.getOpcode() == ISD::TargetGlobalAddress)
1535 return false; // Direct calls.
1537 if (Addr.getOpcode() == ISD::ADD) {
1538 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1539 if (isInt<13>(CN->getSExtValue()))
1540 return false; // Let the reg+imm pattern catch this!
1541 R1 = Addr.getOperand(0);
1542 R2 = Addr.getOperand(1);
1552 // Handle generic address case. It is accessed from inlined asm =m constraints,
1553 // which could have any kind of pointer.
1554 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1555 SDValue &Base, SDValue &Offset) {
1556 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1557 Addr.getOpcode() == ISD::TargetGlobalAddress)
1558 return false; // Direct calls.
1560 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1561 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1562 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1566 if (Addr.getOpcode() == ISD::ADD) {
1567 Base = Addr.getOperand(0);
1568 Offset = Addr.getOperand(1);
1573 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1578 bool HexagonDAGToDAGISel::
1579 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1580 std::vector<SDValue> &OutOps) {
1583 switch (ConstraintCode) {
1584 case 'o': // Offsetable.
1585 case 'v': // Not offsetable.
1586 default: return true;
1587 case 'm': // Memory.
1588 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1593 OutOps.push_back(Op0);
1594 OutOps.push_back(Op1);
1598 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
1599 unsigned UseCount = 0;
1600 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
1604 return (UseCount <= 1);
1608 //===--------------------------------------------------------------------===//
1609 // Return 'true' if use count of the global address is below threshold.
1610 //===--------------------------------------------------------------------===//
1611 bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const {
1612 assert(N->getOpcode() == ISD::TargetGlobalAddress &&
1613 "Expecting a target global address");
1615 // Always try to fold the address.
1616 if (TM.getOptLevel() == CodeGenOpt::Aggressive)
1619 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
1620 DenseMap<const GlobalValue *, unsigned>::const_iterator GI =
1621 GlobalAddressUseCountMap.find(GA->getGlobal());
1623 if (GI == GlobalAddressUseCountMap.end())
1626 return GI->second <= MaxNumOfUsesForConstExtenders;
1629 //===--------------------------------------------------------------------===//
1630 // Return true if the non GP-relative global address can be folded.
1631 //===--------------------------------------------------------------------===//
1632 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
1633 return foldGlobalAddressImpl(N, R, false);
1636 //===--------------------------------------------------------------------===//
1637 // Return true if the GP-relative global address can be folded.
1638 //===--------------------------------------------------------------------===//
1639 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
1640 return foldGlobalAddressImpl(N, R, true);
1643 //===--------------------------------------------------------------------===//
1644 // Fold offset of the global address if number of uses are below threshold.
1645 //===--------------------------------------------------------------------===//
1646 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
1647 bool ShouldLookForGP) {
1648 if (N.getOpcode() == ISD::ADD) {
1649 SDValue N0 = N.getOperand(0);
1650 SDValue N1 = N.getOperand(1);
1651 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
1652 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
1653 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
1654 GlobalAddressSDNode *GA =
1655 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
1658 (GA->getOpcode() == ISD::TargetGlobalAddress)) {
1659 if ((N0.getOpcode() == HexagonISD::CONST32) &&
1660 !hasNumUsesBelowThresGA(GA))
1662 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
1666 (uint64_t)Const->getSExtValue());