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 bool SelectAddrFI(SDValue &N, SDValue &R);
84 const char *getPassName() const override {
85 return "Hexagon DAG->DAG Pattern Instruction Selection";
88 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
89 /// inline asm expressions.
90 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
92 std::vector<SDValue> &OutOps) override;
93 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
95 SDNode *SelectLoad(SDNode *N);
96 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl);
97 SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl);
98 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
100 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
102 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl);
103 SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl);
104 SDNode *SelectStore(SDNode *N);
105 SDNode *SelectSHL(SDNode *N);
106 SDNode *SelectSelect(SDNode *N);
107 SDNode *SelectTruncate(SDNode *N);
108 SDNode *SelectMul(SDNode *N);
109 SDNode *SelectZeroExtend(SDNode *N);
110 SDNode *SelectIntrinsicWOChain(SDNode *N);
111 SDNode *SelectIntrinsicWChain(SDNode *N);
112 SDNode *SelectConstant(SDNode *N);
113 SDNode *SelectConstantFP(SDNode *N);
114 SDNode *SelectAdd(SDNode *N);
115 bool isConstExtProfitable(SDNode *N) const;
117 // XformMskToBitPosU5Imm - Returns the bit position which
118 // the single bit 32 bit mask represents.
119 // Used in Clr and Set bit immediate memops.
120 SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
122 bitPos = Log2_32(Imm);
123 assert(bitPos >= 0 && bitPos < 32 &&
124 "Constant out of range for 32 BitPos Memops");
125 return CurDAG->getTargetConstant(bitPos, MVT::i32);
128 // XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
129 // mask represents. Used in Clr and Set bit immediate memops.
130 SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
131 return XformMskToBitPosU5Imm(Imm);
134 // XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
135 // mask represents. Used in Clr and Set bit immediate memops.
136 SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
137 return XformMskToBitPosU5Imm(Imm);
140 // Return true if there is exactly one bit set in V, i.e., if V is one of the
141 // following integers: 2^0, 2^1, ..., 2^31.
142 bool ImmIsSingleBit(uint32_t v) const {
143 uint32_t c = CountPopulation_64(v);
144 // Only return true if we counted 1 bit.
148 // XformM5ToU5Imm - Return a target constant with the specified value, of type
149 // i32 where the negative literal is transformed into a positive literal for
151 inline SDValue XformM5ToU5Imm(signed Imm) {
152 assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
153 return CurDAG->getTargetConstant( - Imm, MVT::i32);
157 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
158 // [1..128], used in cmpb.gtu instructions.
159 inline SDValue XformU7ToU7M1Imm(signed Imm) {
160 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
161 return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
164 // XformS8ToS8M1Imm - Return a target constant decremented by 1.
165 inline SDValue XformSToSM1Imm(signed Imm) {
166 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
169 // XformU8ToU8M1Imm - Return a target constant decremented by 1.
170 inline SDValue XformUToUM1Imm(unsigned Imm) {
171 assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
172 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
175 // XformSToSM2Imm - Return a target constant decremented by 2.
176 inline SDValue XformSToSM2Imm(unsigned Imm) {
177 return CurDAG->getTargetConstant(Imm - 2, MVT::i32);
180 // XformSToSM3Imm - Return a target constant decremented by 3.
181 inline SDValue XformSToSM3Imm(unsigned Imm) {
182 return CurDAG->getTargetConstant(Imm - 3, MVT::i32);
185 // Include the pieces autogenerated from the target description.
186 #include "HexagonGenDAGISel.inc"
189 bool isValueExtension(SDValue const &Val, unsigned FromBits, SDValue &Src);
191 } // end anonymous namespace
194 /// createHexagonISelDag - This pass converts a legalized DAG into a
195 /// Hexagon-specific DAG, ready for instruction scheduling.
197 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM,
198 CodeGenOpt::Level OptLevel) {
199 return new HexagonDAGToDAGISel(TM, OptLevel);
202 static void initializePassOnce(PassRegistry &Registry) {
203 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
204 PassInfo *PI = new PassInfo(Name, "hexagon-isel",
205 &SelectionDAGISel::ID, nullptr, false, false);
206 Registry.registerPass(*PI, true);
209 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
210 CALL_ONCE_INITIALIZATION(initializePassOnce)
214 static bool IsS11_0_Offset(SDNode * S) {
215 ConstantSDNode *N = cast<ConstantSDNode>(S);
217 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
219 int64_t v = (int64_t)N->getSExtValue();
224 static bool IsS11_1_Offset(SDNode * S) {
225 ConstantSDNode *N = cast<ConstantSDNode>(S);
227 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
229 int64_t v = (int64_t)N->getSExtValue();
230 return isShiftedInt<11,1>(v);
234 static bool IsS11_2_Offset(SDNode * S) {
235 ConstantSDNode *N = cast<ConstantSDNode>(S);
237 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
239 int64_t v = (int64_t)N->getSExtValue();
240 return isShiftedInt<11,2>(v);
244 static bool IsS11_3_Offset(SDNode * S) {
245 ConstantSDNode *N = cast<ConstantSDNode>(S);
247 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
249 int64_t v = (int64_t)N->getSExtValue();
250 return isShiftedInt<11,3>(v);
254 static bool IsU6_0_Offset(SDNode * S) {
255 ConstantSDNode *N = cast<ConstantSDNode>(S);
257 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
259 int64_t v = (int64_t)N->getSExtValue();
264 static bool IsU6_1_Offset(SDNode * S) {
265 ConstantSDNode *N = cast<ConstantSDNode>(S);
267 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
269 int64_t v = (int64_t)N->getSExtValue();
270 return isShiftedUInt<6,1>(v);
274 static bool IsU6_2_Offset(SDNode * S) {
275 ConstantSDNode *N = cast<ConstantSDNode>(S);
277 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
279 int64_t v = (int64_t)N->getSExtValue();
280 return isShiftedUInt<6,2>(v);
284 // Intrinsics that return a a predicate.
285 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
290 case Intrinsic::hexagon_C2_cmpeq:
291 case Intrinsic::hexagon_C2_cmpgt:
292 case Intrinsic::hexagon_C2_cmpgtu:
293 case Intrinsic::hexagon_C2_cmpgtup:
294 case Intrinsic::hexagon_C2_cmpgtp:
295 case Intrinsic::hexagon_C2_cmpeqp:
296 case Intrinsic::hexagon_C2_bitsset:
297 case Intrinsic::hexagon_C2_bitsclr:
298 case Intrinsic::hexagon_C2_cmpeqi:
299 case Intrinsic::hexagon_C2_cmpgti:
300 case Intrinsic::hexagon_C2_cmpgtui:
301 case Intrinsic::hexagon_C2_cmpgei:
302 case Intrinsic::hexagon_C2_cmpgeui:
303 case Intrinsic::hexagon_C2_cmplt:
304 case Intrinsic::hexagon_C2_cmpltu:
305 case Intrinsic::hexagon_C2_bitsclri:
306 case Intrinsic::hexagon_C2_and:
307 case Intrinsic::hexagon_C2_or:
308 case Intrinsic::hexagon_C2_xor:
309 case Intrinsic::hexagon_C2_andn:
310 case Intrinsic::hexagon_C2_not:
311 case Intrinsic::hexagon_C2_orn:
312 case Intrinsic::hexagon_C2_pxfer_map:
313 case Intrinsic::hexagon_C2_any8:
314 case Intrinsic::hexagon_C2_all8:
315 case Intrinsic::hexagon_A2_vcmpbeq:
316 case Intrinsic::hexagon_A2_vcmpbgtu:
317 case Intrinsic::hexagon_A2_vcmpheq:
318 case Intrinsic::hexagon_A2_vcmphgt:
319 case Intrinsic::hexagon_A2_vcmphgtu:
320 case Intrinsic::hexagon_A2_vcmpweq:
321 case Intrinsic::hexagon_A2_vcmpwgt:
322 case Intrinsic::hexagon_A2_vcmpwgtu:
323 case Intrinsic::hexagon_C2_tfrrp:
324 case Intrinsic::hexagon_S2_tstbit_i:
325 case Intrinsic::hexagon_S2_tstbit_r:
330 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
331 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
334 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
337 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
340 if (MemType == MVT::i8 && isInt<11>(Offset)) {
348 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
349 // lowering for GlobalAddress nodes has already turned it into a
352 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) {
353 SDValue Chain = LD->getChain();
354 SDNode* Const32 = LD->getBasePtr().getNode();
357 if (Const32->getOpcode() == HexagonISD::CONST32 &&
358 ISD::isNormalLoad(LD)) {
359 SDValue Base = Const32->getOperand(0);
360 EVT LoadedVT = LD->getMemoryVT();
361 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
362 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
363 MVT PointerTy = getTargetLowering()->getPointerTy();
364 const GlobalValue* GV =
365 cast<GlobalAddressSDNode>(Base)->getGlobal();
367 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
368 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
371 // Figure out base + offset opcode
372 if (LoadedVT == MVT::i64) Opcode = Hexagon::L2_loadrd_io;
373 else if (LoadedVT == MVT::i32) Opcode = Hexagon::L2_loadri_io;
374 else if (LoadedVT == MVT::i16) Opcode = Hexagon::L2_loadrh_io;
375 else if (LoadedVT == MVT::i8) Opcode = Hexagon::L2_loadrb_io;
376 else llvm_unreachable("unknown memory type");
378 // Build indexed load.
379 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
380 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
386 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
387 MemOp[0] = LD->getMemOperand();
388 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
389 ReplaceUses(LD, Result);
394 return SelectCode(LD);
398 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
402 SDValue Chain = LD->getChain();
403 EVT LoadedVT = LD->getMemoryVT();
404 SDValue Base = LD->getBasePtr();
405 SDValue Offset = LD->getOffset();
406 SDNode *OffsetNode = Offset.getNode();
407 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
408 SDValue N1 = LD->getOperand(1);
412 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
413 N1.getNode()->getValueType(0) == MVT::i32) {
414 const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
415 TM.getSubtargetImpl()->getInstrInfo());
416 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
417 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
418 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
419 MVT::Other, Base, TargetConst,
421 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64,
422 SDValue(Result_1, 0));
423 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
424 MemOp[0] = LD->getMemOperand();
425 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
426 const SDValue Froms[] = { SDValue(LD, 0),
430 const SDValue Tos[] = { SDValue(Result_2, 0),
431 SDValue(Result_1, 1),
434 ReplaceUses(Froms, Tos, 3);
437 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
438 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
439 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
440 MVT::Other, Base, TargetConst0,
442 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl,
443 MVT::i64, SDValue(Result_1, 0));
444 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
445 MVT::i32, Base, TargetConstVal,
446 SDValue(Result_1, 1));
447 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
448 MemOp[0] = LD->getMemOperand();
449 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
450 const SDValue Froms[] = { SDValue(LD, 0),
454 const SDValue Tos[] = { SDValue(Result_2, 0),
455 SDValue(Result_3, 0),
458 ReplaceUses(Froms, Tos, 3);
461 return SelectCode(LD);
465 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
469 SDValue Chain = LD->getChain();
470 EVT LoadedVT = LD->getMemoryVT();
471 SDValue Base = LD->getBasePtr();
472 SDValue Offset = LD->getOffset();
473 SDNode *OffsetNode = Offset.getNode();
474 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
475 SDValue N1 = LD->getOperand(1);
479 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
480 N1.getNode()->getValueType(0) == MVT::i32) {
481 const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
482 TM.getSubtargetImpl()->getInstrInfo());
483 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
484 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
485 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
486 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
487 MVT::i32, MVT::Other, Base,
488 TargetConstVal, Chain);
489 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
491 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
492 MVT::i64, MVT::Other,
494 SDValue(Result_1,0));
495 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
496 MemOp[0] = LD->getMemOperand();
497 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
498 const SDValue Froms[] = { SDValue(LD, 0),
502 const SDValue Tos[] = { SDValue(Result_3, 0),
503 SDValue(Result_1, 1),
506 ReplaceUses(Froms, Tos, 3);
510 // Generate an indirect load.
511 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
512 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
513 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
515 Base, TargetConst0, Chain);
516 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
518 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
519 MVT::i64, MVT::Other,
521 SDValue(Result_1,0));
522 // Add offset to base.
523 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
524 Base, TargetConstVal,
525 SDValue(Result_1, 1));
526 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
527 MemOp[0] = LD->getMemOperand();
528 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
529 const SDValue Froms[] = { SDValue(LD, 0),
533 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
534 SDValue(Result_4, 0), // New address.
537 ReplaceUses(Froms, Tos, 3);
541 return SelectCode(LD);
545 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
546 SDValue Chain = LD->getChain();
547 SDValue Base = LD->getBasePtr();
548 SDValue Offset = LD->getOffset();
549 SDNode *OffsetNode = Offset.getNode();
550 // Get the constant value.
551 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
552 EVT LoadedVT = LD->getMemoryVT();
555 // Check for zero ext loads.
556 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
558 // Figure out the opcode.
559 const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
560 TM.getSubtargetImpl()->getInstrInfo());
561 if (LoadedVT == MVT::i64) {
562 if (TII->isValidAutoIncImm(LoadedVT, Val))
563 Opcode = Hexagon::L2_loadrd_pi;
565 Opcode = Hexagon::L2_loadrd_io;
566 } else if (LoadedVT == MVT::i32) {
567 if (TII->isValidAutoIncImm(LoadedVT, Val))
568 Opcode = Hexagon::L2_loadri_pi;
570 Opcode = Hexagon::L2_loadri_io;
571 } else if (LoadedVT == MVT::i16) {
572 if (TII->isValidAutoIncImm(LoadedVT, Val))
573 Opcode = zextval ? Hexagon::L2_loadruh_pi : Hexagon::L2_loadrh_pi;
575 Opcode = zextval ? Hexagon::L2_loadruh_io : Hexagon::L2_loadrh_io;
576 } else if (LoadedVT == MVT::i8) {
577 if (TII->isValidAutoIncImm(LoadedVT, Val))
578 Opcode = zextval ? Hexagon::L2_loadrub_pi : Hexagon::L2_loadrb_pi;
580 Opcode = zextval ? Hexagon::L2_loadrub_io : Hexagon::L2_loadrb_io;
582 llvm_unreachable("unknown memory type");
584 // For zero ext i64 loads, we need to add combine instructions.
585 if (LD->getValueType(0) == MVT::i64 &&
586 LD->getExtensionType() == ISD::ZEXTLOAD) {
587 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
589 if (LD->getValueType(0) == MVT::i64 &&
590 LD->getExtensionType() == ISD::SEXTLOAD) {
591 // Handle sign ext i64 loads.
592 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
594 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
595 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
596 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
598 MVT::i32, MVT::Other, Base,
599 TargetConstVal, Chain);
600 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
601 MemOp[0] = LD->getMemOperand();
602 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
603 const SDValue Froms[] = { SDValue(LD, 0),
607 const SDValue Tos[] = { SDValue(Result, 0),
611 ReplaceUses(Froms, Tos, 3);
614 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
615 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
616 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
618 MVT::Other, Base, TargetConst0,
620 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
621 Base, TargetConstVal,
622 SDValue(Result_1, 1));
623 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
624 MemOp[0] = LD->getMemOperand();
625 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
626 const SDValue Froms[] = { SDValue(LD, 0),
630 const SDValue Tos[] = { SDValue(Result_1, 0),
631 SDValue(Result_2, 0),
634 ReplaceUses(Froms, Tos, 3);
640 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
643 LoadSDNode *LD = cast<LoadSDNode>(N);
644 ISD::MemIndexedMode AM = LD->getAddressingMode();
646 // Handle indexed loads.
647 if (AM != ISD::UNINDEXED) {
648 result = SelectIndexedLoad(LD, dl);
650 result = SelectBaseOffsetLoad(LD, dl);
657 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
658 SDValue Chain = ST->getChain();
659 SDValue Base = ST->getBasePtr();
660 SDValue Offset = ST->getOffset();
661 SDValue Value = ST->getValue();
662 SDNode *OffsetNode = Offset.getNode();
663 // Get the constant value.
664 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
665 EVT StoredVT = ST->getMemoryVT();
667 // Offset value must be within representable range
668 // and must have correct alignment properties.
669 const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
670 TM.getSubtargetImpl()->getInstrInfo());
671 if (TII->isValidAutoIncImm(StoredVT, Val)) {
672 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
676 // Figure out the post inc version of opcode.
677 if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_pi;
678 else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_pi;
679 else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_pi;
680 else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_pi;
681 else llvm_unreachable("unknown memory type");
683 // Build post increment store.
684 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
686 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
687 MemOp[0] = ST->getMemOperand();
688 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
690 ReplaceUses(ST, Result);
691 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
695 // Note: Order of operands matches the def of instruction:
696 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
697 // and it differs for POST_ST* for instance.
698 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
702 // Figure out the opcode.
703 if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
704 else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
705 else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
706 else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
707 else llvm_unreachable("unknown memory type");
709 // Build regular store.
710 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
711 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
712 // Build splitted incriment instruction.
713 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
716 SDValue(Result_1, 0));
717 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
718 MemOp[0] = ST->getMemOperand();
719 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
721 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
722 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
727 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
729 SDValue Chain = ST->getChain();
730 SDNode* Const32 = ST->getBasePtr().getNode();
731 SDValue Value = ST->getValue();
734 // Try to lower stores of GlobalAdresses into indexed stores. Custom
735 // lowering for GlobalAddress nodes has already turned it into a
736 // CONST32. Avoid truncating stores for the moment. Post-inc stores
737 // do the same. Don't think there's a reason for it, so will file a
739 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
740 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
741 SDValue Base = Const32->getOperand(0);
742 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
743 EVT StoredVT = ST->getMemoryVT();
744 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
745 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
746 MVT PointerTy = getTargetLowering()->getPointerTy();
747 const GlobalValue* GV =
748 cast<GlobalAddressSDNode>(Base)->getGlobal();
750 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
751 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
755 // Figure out base + offset opcode
756 if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
757 else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
758 else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
759 else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
760 else llvm_unreachable("unknown memory type");
762 SDValue Ops[] = {SDValue(NewBase,0),
763 CurDAG->getTargetConstant(Offset,PointerTy),
765 // build indexed store
766 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
768 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
769 MemOp[0] = ST->getMemOperand();
770 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
771 ReplaceUses(ST, Result);
777 return SelectCode(ST);
781 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
783 StoreSDNode *ST = cast<StoreSDNode>(N);
784 ISD::MemIndexedMode AM = ST->getAddressingMode();
786 // Handle indexed stores.
787 if (AM != ISD::UNINDEXED) {
788 return SelectIndexedStore(ST, dl);
791 return SelectBaseOffsetStore(ST, dl);
794 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
798 // %conv.i = sext i32 %tmp1 to i64
799 // %conv2.i = sext i32 %add to i64
800 // %mul.i = mul nsw i64 %conv2.i, %conv.i
802 // --- match with the following ---
804 // %mul.i = mpy (%tmp1, %add)
807 if (N->getValueType(0) == MVT::i64) {
808 // Shifting a i64 signed multiply.
809 SDValue MulOp0 = N->getOperand(0);
810 SDValue MulOp1 = N->getOperand(1);
815 // Handle sign_extend and sextload.
816 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
817 SDValue Sext0 = MulOp0.getOperand(0);
818 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
819 return SelectCode(N);
823 } else if (MulOp0.getOpcode() == ISD::LOAD) {
824 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
825 if (LD->getMemoryVT() != MVT::i32 ||
826 LD->getExtensionType() != ISD::SEXTLOAD ||
827 LD->getAddressingMode() != ISD::UNINDEXED) {
828 return SelectCode(N);
831 SDValue Chain = LD->getChain();
832 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
833 OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
835 LD->getBasePtr(), TargetConst0,
838 return SelectCode(N);
841 // Same goes for the second operand.
842 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
843 SDValue Sext1 = MulOp1.getOperand(0);
844 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
845 return SelectCode(N);
849 } else if (MulOp1.getOpcode() == ISD::LOAD) {
850 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.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 OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
861 LD->getBasePtr(), TargetConst0,
864 return SelectCode(N);
867 // Generate a mpy instruction.
868 SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl, MVT::i64,
870 ReplaceUses(N, Result);
874 return SelectCode(N);
878 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
880 SDValue N0 = N->getOperand(0);
881 if (N0.getOpcode() == ISD::SETCC) {
882 SDValue N00 = N0.getOperand(0);
883 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
884 SDValue N000 = N00.getOperand(0);
885 SDValue N001 = N00.getOperand(1);
886 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
887 SDValue N01 = N0.getOperand(1);
888 SDValue N02 = N0.getOperand(2);
890 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
891 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
892 // IntRegs:i32:$src2)
893 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
894 // Pattern complexity = 9 cost = 1 size = 0.
895 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
896 SDValue N1 = N->getOperand(1);
898 SDValue N2 = N->getOperand(2);
900 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
901 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
902 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
904 SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_max, dl,
906 SDValue(SextNode, 0),
908 ReplaceUses(N, Result);
914 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
915 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
916 // IntRegs:i32:$src2)
917 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
918 // Pattern complexity = 9 cost = 1 size = 0.
919 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
920 SDValue N1 = N->getOperand(1);
922 SDValue N2 = N->getOperand(2);
924 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
925 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
926 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
928 SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_min, dl,
930 SDValue(SextNode, 0),
932 ReplaceUses(N, Result);
941 return SelectCode(N);
945 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
947 SDValue Shift = N->getOperand(0);
950 // %conv.i = sext i32 %tmp1 to i64
951 // %conv2.i = sext i32 %add to i64
952 // %mul.i = mul nsw i64 %conv2.i, %conv.i
953 // %shr5.i = lshr i64 %mul.i, 32
954 // %conv3.i = trunc i64 %shr5.i to i32
956 // --- match with the following ---
958 // %conv3.i = mpy (%tmp1, %add)
961 if (N->getValueType(0) == MVT::i32) {
963 if (Shift.getNode()->getValueType(0) == MVT::i64) {
964 // Trunc child is logical shift right.
965 if (Shift.getOpcode() != ISD::SRL) {
966 return SelectCode(N);
969 SDValue ShiftOp0 = Shift.getOperand(0);
970 SDValue ShiftOp1 = Shift.getOperand(1);
973 if (ShiftOp1.getOpcode() != ISD::Constant) {
974 return SelectCode(N);
978 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
979 if (ShiftConst != 32) {
980 return SelectCode(N);
983 // Shifting a i64 signed multiply
984 SDValue Mul = ShiftOp0;
985 if (Mul.getOpcode() != ISD::MUL) {
986 return SelectCode(N);
989 SDValue MulOp0 = Mul.getOperand(0);
990 SDValue MulOp1 = Mul.getOperand(1);
995 // Handle sign_extend and sextload
996 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
997 SDValue Sext0 = MulOp0.getOperand(0);
998 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
999 return SelectCode(N);
1003 } else if (MulOp0.getOpcode() == ISD::LOAD) {
1004 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
1005 if (LD->getMemoryVT() != MVT::i32 ||
1006 LD->getExtensionType() != ISD::SEXTLOAD ||
1007 LD->getAddressingMode() != ISD::UNINDEXED) {
1008 return SelectCode(N);
1011 SDValue Chain = LD->getChain();
1012 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1013 OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
1016 TargetConst0, Chain), 0);
1018 return SelectCode(N);
1021 // Same goes for the second operand.
1022 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
1023 SDValue Sext1 = MulOp1.getOperand(0);
1024 if (Sext1.getNode()->getValueType(0) != MVT::i32)
1025 return SelectCode(N);
1028 } else if (MulOp1.getOpcode() == ISD::LOAD) {
1029 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
1030 if (LD->getMemoryVT() != MVT::i32 ||
1031 LD->getExtensionType() != ISD::SEXTLOAD ||
1032 LD->getAddressingMode() != ISD::UNINDEXED) {
1033 return SelectCode(N);
1036 SDValue Chain = LD->getChain();
1037 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1038 OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
1041 TargetConst0, Chain), 0);
1043 return SelectCode(N);
1046 // Generate a mpy instruction.
1047 SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_mpy_up, dl, MVT::i32,
1049 ReplaceUses(N, Result);
1054 return SelectCode(N);
1058 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
1060 if (N->getValueType(0) == MVT::i32) {
1061 SDValue Shl_0 = N->getOperand(0);
1062 SDValue Shl_1 = N->getOperand(1);
1064 if (Shl_1.getOpcode() == ISD::Constant) {
1065 if (Shl_0.getOpcode() == ISD::MUL) {
1066 SDValue Mul_0 = Shl_0.getOperand(0); // Val
1067 SDValue Mul_1 = Shl_0.getOperand(1); // Const
1068 // RHS of mul is const.
1069 if (Mul_1.getOpcode() == ISD::Constant) {
1071 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1073 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1074 int32_t ValConst = MulConst << ShlConst;
1075 SDValue Val = CurDAG->getTargetConstant(ValConst,
1077 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1078 if (isInt<9>(CN->getSExtValue())) {
1080 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
1081 MVT::i32, Mul_0, Val);
1082 ReplaceUses(N, Result);
1087 } else if (Shl_0.getOpcode() == ISD::SUB) {
1088 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1089 SDValue Sub_1 = Shl_0.getOperand(1); // Val
1090 if (Sub_0.getOpcode() == ISD::Constant) {
1092 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1093 if (SubConst == 0) {
1094 if (Sub_1.getOpcode() == ISD::SHL) {
1095 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1096 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1097 if (Shl2_1.getOpcode() == ISD::Constant) {
1099 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1101 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1102 int32_t ValConst = 1 << (ShlConst+Shl2Const);
1103 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1104 if (ConstantSDNode *CN =
1105 dyn_cast<ConstantSDNode>(Val.getNode()))
1106 if (isInt<9>(CN->getSExtValue())) {
1108 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, MVT::i32,
1110 ReplaceUses(N, Result);
1120 return SelectCode(N);
1125 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1126 // result of the intrinsic is predicate); convert the zero_extend to
1127 // transfer instruction.
1129 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1130 // converted into a MUX as predicate registers defined as 1 bit in the
1131 // compiler. Architecture defines them as 8-bit registers.
1132 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1134 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1136 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1137 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1139 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1140 if (doesIntrinsicReturnPredicate(ID)) {
1141 // Now we need to differentiate target data types.
1142 if (N->getValueType(0) == MVT::i64) {
1143 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1144 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1145 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
1147 SDValue(IsIntrinsic, 0));
1148 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl,
1151 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
1152 MVT::i64, MVT::Other,
1153 SDValue(Result_2, 0),
1154 SDValue(Result_1, 0));
1155 ReplaceUses(N, Result_3);
1158 if (N->getValueType(0) == MVT::i32) {
1159 // Convert the zero_extend to Rs = Pd
1160 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
1162 SDValue(IsIntrinsic, 0));
1163 ReplaceUses(N, RsPd);
1166 llvm_unreachable("Unexpected value type");
1169 return SelectCode(N);
1173 // Checking for intrinsics which have predicate registers as operand(s)
1174 // and lowering to the actual intrinsic.
1176 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1177 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1180 case Intrinsic::hexagon_S2_vsplatrb:
1183 case Intrinsic::hexagon_S2_vsplatrh:
1187 return SelectCode(N);
1190 SDValue const &V = N->getOperand(1);
1192 if (isValueExtension(V, Bits, U)) {
1193 SDValue R = CurDAG->getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
1194 N->getOperand(0), U);
1195 return SelectCode(R.getNode());
1197 return SelectCode(N);
1201 // Map floating point constant values.
1203 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1205 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1206 APFloat APF = CN->getValueAPF();
1207 if (N->getValueType(0) == MVT::f32) {
1208 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1209 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1211 else if (N->getValueType(0) == MVT::f64) {
1212 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1213 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1216 return SelectCode(N);
1221 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1223 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1225 if (N->getValueType(0) == MVT::i1) {
1227 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1229 // Create the IntReg = 1 node.
1231 CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
1232 CurDAG->getTargetConstant(0, MVT::i32));
1235 SDNode* Pd = CurDAG->getMachineNode(Hexagon::C2_tfrrp, dl, MVT::i1,
1236 SDValue(IntRegTFR, 0));
1239 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::C2_not, dl, MVT::i1,
1243 Result = CurDAG->getMachineNode(Hexagon::C2_xor, dl, MVT::i1,
1244 SDValue(Pd, 0), SDValue(NotPd, 0));
1246 // We have just built:
1248 // Pd = xor(not(Pd), Pd)
1250 ReplaceUses(N, Result);
1255 return SelectCode(N);
1260 // Map add followed by a asr -> asr +=.
1262 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1264 if (N->getValueType(0) != MVT::i32) {
1265 return SelectCode(N);
1267 // Identify nodes of the form: add(asr(...)).
1268 SDNode* Src1 = N->getOperand(0).getNode();
1269 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1270 || Src1->getValueType(0) != MVT::i32) {
1271 return SelectCode(N);
1274 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1275 // Rd and Rd' are assigned to the same register
1276 SDNode* Result = CurDAG->getMachineNode(Hexagon::S2_asr_r_r_acc, dl, MVT::i32,
1278 Src1->getOperand(0),
1279 Src1->getOperand(1));
1280 ReplaceUses(N, Result);
1286 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1287 if (N->isMachineOpcode()) {
1289 return nullptr; // Already selected.
1293 switch (N->getOpcode()) {
1295 return SelectConstant(N);
1297 case ISD::ConstantFP:
1298 return SelectConstantFP(N);
1301 return SelectAdd(N);
1304 return SelectSHL(N);
1307 return SelectLoad(N);
1310 return SelectStore(N);
1313 return SelectSelect(N);
1316 return SelectTruncate(N);
1319 return SelectMul(N);
1321 case ISD::ZERO_EXTEND:
1322 return SelectZeroExtend(N);
1324 case ISD::INTRINSIC_WO_CHAIN:
1325 return SelectIntrinsicWOChain(N);
1328 return SelectCode(N);
1333 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1334 // to define these instructions.
1336 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1338 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1339 Addr.getOpcode() == ISD::TargetGlobalAddress)
1340 return false; // Direct calls.
1342 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1343 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1344 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1348 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1353 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1355 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1356 Addr.getOpcode() == ISD::TargetGlobalAddress)
1357 return false; // Direct calls.
1359 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1360 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1361 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1362 return (IsS11_0_Offset(Offset.getNode()));
1365 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1366 return (IsS11_0_Offset(Offset.getNode()));
1370 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1372 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1373 Addr.getOpcode() == ISD::TargetGlobalAddress)
1374 return false; // Direct calls.
1376 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1377 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1378 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1379 return (IsS11_1_Offset(Offset.getNode()));
1382 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1383 return (IsS11_1_Offset(Offset.getNode()));
1387 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1389 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1390 Addr.getOpcode() == ISD::TargetGlobalAddress)
1391 return false; // Direct calls.
1393 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1394 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1395 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1396 return (IsS11_2_Offset(Offset.getNode()));
1399 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1400 return (IsS11_2_Offset(Offset.getNode()));
1404 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1406 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1407 Addr.getOpcode() == ISD::TargetGlobalAddress)
1408 return false; // Direct calls.
1410 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1411 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1412 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1413 return (IsU6_0_Offset(Offset.getNode()));
1416 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1417 return (IsU6_0_Offset(Offset.getNode()));
1421 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1423 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1424 Addr.getOpcode() == ISD::TargetGlobalAddress)
1425 return false; // Direct calls.
1427 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1428 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1429 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1430 return (IsU6_1_Offset(Offset.getNode()));
1433 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1434 return (IsU6_1_Offset(Offset.getNode()));
1438 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1440 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1441 Addr.getOpcode() == ISD::TargetGlobalAddress)
1442 return false; // Direct calls.
1444 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1445 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1446 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1447 return (IsU6_2_Offset(Offset.getNode()));
1450 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1451 return (IsU6_2_Offset(Offset.getNode()));
1455 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1458 if (Addr.getOpcode() != ISD::ADD) {
1459 return(SelectADDRriS11_2(Addr, Base, Offset));
1462 return SelectADDRriS11_2(Addr, Base, Offset);
1466 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1468 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1469 Addr.getOpcode() == ISD::TargetGlobalAddress)
1470 return false; // Direct calls.
1472 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1473 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1474 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1475 return (IsS11_3_Offset(Offset.getNode()));
1478 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1479 return (IsS11_3_Offset(Offset.getNode()));
1482 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1484 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1485 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1486 Addr.getOpcode() == ISD::TargetGlobalAddress)
1487 return false; // Direct calls.
1489 if (Addr.getOpcode() == ISD::ADD) {
1490 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1491 if (isInt<13>(CN->getSExtValue()))
1492 return false; // Let the reg+imm pattern catch this!
1493 R1 = Addr.getOperand(0);
1494 R2 = Addr.getOperand(1);
1504 // Handle generic address case. It is accessed from inlined asm =m constraints,
1505 // which could have any kind of pointer.
1506 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1507 SDValue &Base, SDValue &Offset) {
1508 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1509 Addr.getOpcode() == ISD::TargetGlobalAddress)
1510 return false; // Direct calls.
1512 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1513 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1514 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1518 if (Addr.getOpcode() == ISD::ADD) {
1519 Base = Addr.getOperand(0);
1520 Offset = Addr.getOperand(1);
1525 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1530 bool HexagonDAGToDAGISel::
1531 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1532 std::vector<SDValue> &OutOps) {
1535 switch (ConstraintCode) {
1536 case 'o': // Offsetable.
1537 case 'v': // Not offsetable.
1538 default: return true;
1539 case 'm': // Memory.
1540 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1545 OutOps.push_back(Op0);
1546 OutOps.push_back(Op1);
1550 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
1551 unsigned UseCount = 0;
1552 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
1556 return (UseCount <= 1);
1560 //===--------------------------------------------------------------------===//
1561 // Return 'true' if use count of the global address is below threshold.
1562 //===--------------------------------------------------------------------===//
1563 bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const {
1564 assert(N->getOpcode() == ISD::TargetGlobalAddress &&
1565 "Expecting a target global address");
1567 // Always try to fold the address.
1568 if (TM.getOptLevel() == CodeGenOpt::Aggressive)
1571 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
1572 DenseMap<const GlobalValue *, unsigned>::const_iterator GI =
1573 GlobalAddressUseCountMap.find(GA->getGlobal());
1575 if (GI == GlobalAddressUseCountMap.end())
1578 return GI->second <= MaxNumOfUsesForConstExtenders;
1581 //===--------------------------------------------------------------------===//
1582 // Return true if the non-GP-relative global address can be folded.
1583 //===--------------------------------------------------------------------===//
1584 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
1585 return foldGlobalAddressImpl(N, R, false);
1588 //===--------------------------------------------------------------------===//
1589 // Return true if the GP-relative global address can be folded.
1590 //===--------------------------------------------------------------------===//
1591 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
1592 return foldGlobalAddressImpl(N, R, true);
1595 //===--------------------------------------------------------------------===//
1596 // Fold offset of the global address if number of uses are below threshold.
1597 //===--------------------------------------------------------------------===//
1598 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
1599 bool ShouldLookForGP) {
1600 if (N.getOpcode() == ISD::ADD) {
1601 SDValue N0 = N.getOperand(0);
1602 SDValue N1 = N.getOperand(1);
1603 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
1604 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
1605 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
1606 GlobalAddressSDNode *GA =
1607 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
1610 (GA->getOpcode() == ISD::TargetGlobalAddress)) {
1611 if ((N0.getOpcode() == HexagonISD::CONST32) &&
1612 !hasNumUsesBelowThresGA(GA))
1614 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
1618 (uint64_t)Const->getSExtValue());
1626 bool HexagonDAGToDAGISel::SelectAddrFI(SDValue& N, SDValue &R) {
1627 if (N.getOpcode() != ISD::FrameIndex)
1629 FrameIndexSDNode *FX = cast<FrameIndexSDNode>(N);
1630 R = CurDAG->getTargetFrameIndex(FX->getIndex(), MVT::i32);
1634 bool HexagonDAGToDAGISel::isValueExtension(SDValue const &Val,
1635 unsigned FromBits, SDValue &Src) {
1636 unsigned Opc = Val.getOpcode();
1638 case ISD::SIGN_EXTEND:
1639 case ISD::ZERO_EXTEND:
1640 case ISD::ANY_EXTEND: {
1641 SDValue const &Op0 = Val.getOperand(0);
1642 EVT T = Op0.getValueType();
1643 if (T.isInteger() && T.getSizeInBits() == FromBits) {
1649 case ISD::SIGN_EXTEND_INREG:
1650 case ISD::AssertSext:
1651 case ISD::AssertZext:
1652 if (Val.getOperand(0).getValueType().isInteger()) {
1653 VTSDNode *T = cast<VTSDNode>(Val.getOperand(1));
1654 if (T->getVT().getSizeInBits() == FromBits) {
1655 Src = Val.getOperand(0);
1661 // Check if this is an AND with "FromBits" of lower bits set to 1.
1662 uint64_t FromMask = (1 << FromBits) - 1;
1663 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
1664 if (C->getZExtValue() == FromMask) {
1665 Src = Val.getOperand(1);
1669 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
1670 if (C->getZExtValue() == FromMask) {
1671 Src = Val.getOperand(0);
1679 // OR/XOR with the lower "FromBits" bits set to 0.
1680 uint64_t FromMask = (1 << FromBits) - 1;
1681 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
1682 if ((C->getZExtValue() & FromMask) == 0) {
1683 Src = Val.getOperand(1);
1687 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
1688 if ((C->getZExtValue() & FromMask) == 0) {
1689 Src = Val.getOperand(0);