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;
55 explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine,
56 CodeGenOpt::Level OptLevel)
57 : SelectionDAGISel(targetmachine, OptLevel), TM(targetmachine) {
58 initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
60 bool hasNumUsesBelowThresGA(SDNode *N) const;
62 SDNode *Select(SDNode *N) override;
64 // Complex Pattern Selectors.
65 inline bool foldGlobalAddress(SDValue &N, SDValue &R);
66 inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
67 bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
68 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
69 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
70 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
71 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
72 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
73 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
74 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
75 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
76 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
77 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
79 // Complex Pattern Selectors.
80 inline bool SelectAddrGA(SDValue &N, SDValue &R);
81 inline bool SelectAddrGP(SDValue &N, SDValue &R);
82 bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP);
83 bool SelectAddrFI(SDValue &N, SDValue &R);
85 const char *getPassName() const override {
86 return "Hexagon DAG->DAG Pattern Instruction Selection";
89 bool runOnMachineFunction(MachineFunction &MF) override {
90 Subtarget = &MF.getSubtarget<HexagonSubtarget>();
91 return SelectionDAGISel::runOnMachineFunction(MF);
94 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
95 /// inline asm expressions.
96 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
98 std::vector<SDValue> &OutOps) override;
99 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
101 SDNode *SelectLoad(SDNode *N);
102 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl);
103 SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl);
104 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
106 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
108 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl);
109 SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl);
110 SDNode *SelectStore(SDNode *N);
111 SDNode *SelectSHL(SDNode *N);
112 SDNode *SelectSelect(SDNode *N);
113 SDNode *SelectTruncate(SDNode *N);
114 SDNode *SelectMul(SDNode *N);
115 SDNode *SelectZeroExtend(SDNode *N);
116 SDNode *SelectIntrinsicWOChain(SDNode *N);
117 SDNode *SelectIntrinsicWChain(SDNode *N);
118 SDNode *SelectConstant(SDNode *N);
119 SDNode *SelectConstantFP(SDNode *N);
120 SDNode *SelectAdd(SDNode *N);
122 // XformMskToBitPosU5Imm - Returns the bit position which
123 // the single bit 32 bit mask represents.
124 // Used in Clr and Set bit immediate memops.
125 SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
127 bitPos = Log2_32(Imm);
128 assert(bitPos >= 0 && bitPos < 32 &&
129 "Constant out of range for 32 BitPos Memops");
130 return CurDAG->getTargetConstant(bitPos, MVT::i32);
133 // XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
134 // mask represents. Used in Clr and Set bit immediate memops.
135 SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
136 return XformMskToBitPosU5Imm(Imm);
139 // XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
140 // mask represents. Used in Clr and Set bit immediate memops.
141 SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
142 return XformMskToBitPosU5Imm(Imm);
145 // Return true if there is exactly one bit set in V, i.e., if V is one of the
146 // following integers: 2^0, 2^1, ..., 2^31.
147 bool ImmIsSingleBit(uint32_t v) const {
148 return isPowerOf2_32(v);
151 // XformM5ToU5Imm - Return a target constant with the specified value, of type
152 // i32 where the negative literal is transformed into a positive literal for
154 inline SDValue XformM5ToU5Imm(signed Imm) {
155 assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
156 return CurDAG->getTargetConstant( - Imm, MVT::i32);
160 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
161 // [1..128], used in cmpb.gtu instructions.
162 inline SDValue XformU7ToU7M1Imm(signed Imm) {
163 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
164 return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
167 // XformS8ToS8M1Imm - Return a target constant decremented by 1.
168 inline SDValue XformSToSM1Imm(signed Imm) {
169 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
172 // XformU8ToU8M1Imm - Return a target constant decremented by 1.
173 inline SDValue XformUToUM1Imm(unsigned Imm) {
174 assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
175 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
178 // XformSToSM2Imm - Return a target constant decremented by 2.
179 inline SDValue XformSToSM2Imm(unsigned Imm) {
180 return CurDAG->getTargetConstant(Imm - 2, MVT::i32);
183 // XformSToSM3Imm - Return a target constant decremented by 3.
184 inline SDValue XformSToSM3Imm(unsigned Imm) {
185 return CurDAG->getTargetConstant(Imm - 3, MVT::i32);
188 // Include the pieces autogenerated from the target description.
189 #include "HexagonGenDAGISel.inc"
192 bool isValueExtension(SDValue const &Val, unsigned FromBits, SDValue &Src);
194 } // end anonymous namespace
197 /// createHexagonISelDag - This pass converts a legalized DAG into a
198 /// Hexagon-specific DAG, ready for instruction scheduling.
200 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM,
201 CodeGenOpt::Level OptLevel) {
202 return new HexagonDAGToDAGISel(TM, OptLevel);
205 static void initializePassOnce(PassRegistry &Registry) {
206 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
207 PassInfo *PI = new PassInfo(Name, "hexagon-isel",
208 &SelectionDAGISel::ID, nullptr, false, false);
209 Registry.registerPass(*PI, true);
212 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
213 CALL_ONCE_INITIALIZATION(initializePassOnce)
217 static bool IsS11_0_Offset(SDNode * S) {
218 ConstantSDNode *N = cast<ConstantSDNode>(S);
220 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
222 int64_t v = (int64_t)N->getSExtValue();
227 static bool IsS11_1_Offset(SDNode * S) {
228 ConstantSDNode *N = cast<ConstantSDNode>(S);
230 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
232 int64_t v = (int64_t)N->getSExtValue();
233 return isShiftedInt<11,1>(v);
237 static bool IsS11_2_Offset(SDNode * S) {
238 ConstantSDNode *N = cast<ConstantSDNode>(S);
240 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
242 int64_t v = (int64_t)N->getSExtValue();
243 return isShiftedInt<11,2>(v);
247 static bool IsS11_3_Offset(SDNode * S) {
248 ConstantSDNode *N = cast<ConstantSDNode>(S);
250 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
252 int64_t v = (int64_t)N->getSExtValue();
253 return isShiftedInt<11,3>(v);
257 static bool IsU6_0_Offset(SDNode * S) {
258 ConstantSDNode *N = cast<ConstantSDNode>(S);
260 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
262 int64_t v = (int64_t)N->getSExtValue();
267 static bool IsU6_1_Offset(SDNode * S) {
268 ConstantSDNode *N = cast<ConstantSDNode>(S);
270 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
272 int64_t v = (int64_t)N->getSExtValue();
273 return isShiftedUInt<6,1>(v);
277 static bool IsU6_2_Offset(SDNode * S) {
278 ConstantSDNode *N = cast<ConstantSDNode>(S);
280 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
282 int64_t v = (int64_t)N->getSExtValue();
283 return isShiftedUInt<6,2>(v);
287 // Intrinsics that return a a predicate.
288 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
293 case Intrinsic::hexagon_C2_cmpeq:
294 case Intrinsic::hexagon_C2_cmpgt:
295 case Intrinsic::hexagon_C2_cmpgtu:
296 case Intrinsic::hexagon_C2_cmpgtup:
297 case Intrinsic::hexagon_C2_cmpgtp:
298 case Intrinsic::hexagon_C2_cmpeqp:
299 case Intrinsic::hexagon_C2_bitsset:
300 case Intrinsic::hexagon_C2_bitsclr:
301 case Intrinsic::hexagon_C2_cmpeqi:
302 case Intrinsic::hexagon_C2_cmpgti:
303 case Intrinsic::hexagon_C2_cmpgtui:
304 case Intrinsic::hexagon_C2_cmpgei:
305 case Intrinsic::hexagon_C2_cmpgeui:
306 case Intrinsic::hexagon_C2_cmplt:
307 case Intrinsic::hexagon_C2_cmpltu:
308 case Intrinsic::hexagon_C2_bitsclri:
309 case Intrinsic::hexagon_C2_and:
310 case Intrinsic::hexagon_C2_or:
311 case Intrinsic::hexagon_C2_xor:
312 case Intrinsic::hexagon_C2_andn:
313 case Intrinsic::hexagon_C2_not:
314 case Intrinsic::hexagon_C2_orn:
315 case Intrinsic::hexagon_C2_pxfer_map:
316 case Intrinsic::hexagon_C2_any8:
317 case Intrinsic::hexagon_C2_all8:
318 case Intrinsic::hexagon_A2_vcmpbeq:
319 case Intrinsic::hexagon_A2_vcmpbgtu:
320 case Intrinsic::hexagon_A2_vcmpheq:
321 case Intrinsic::hexagon_A2_vcmphgt:
322 case Intrinsic::hexagon_A2_vcmphgtu:
323 case Intrinsic::hexagon_A2_vcmpweq:
324 case Intrinsic::hexagon_A2_vcmpwgt:
325 case Intrinsic::hexagon_A2_vcmpwgtu:
326 case Intrinsic::hexagon_C2_tfrrp:
327 case Intrinsic::hexagon_S2_tstbit_i:
328 case Intrinsic::hexagon_S2_tstbit_r:
334 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
338 SDValue Chain = LD->getChain();
339 EVT LoadedVT = LD->getMemoryVT();
340 SDValue Base = LD->getBasePtr();
341 SDValue Offset = LD->getOffset();
342 SDNode *OffsetNode = Offset.getNode();
343 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
344 SDValue N1 = LD->getOperand(1);
348 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
349 N1.getNode()->getValueType(0) == MVT::i32) {
350 const HexagonInstrInfo *TII = Subtarget->getInstrInfo();
351 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
352 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
353 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
354 MVT::Other, Base, TargetConst,
356 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64,
357 SDValue(Result_1, 0));
358 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
359 MemOp[0] = LD->getMemOperand();
360 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
361 const SDValue Froms[] = { SDValue(LD, 0),
365 const SDValue Tos[] = { SDValue(Result_2, 0),
366 SDValue(Result_1, 1),
369 ReplaceUses(Froms, Tos, 3);
372 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
373 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
374 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
375 MVT::Other, Base, TargetConst0,
377 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl,
378 MVT::i64, SDValue(Result_1, 0));
379 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::A2_addi, dl,
380 MVT::i32, Base, TargetConstVal,
381 SDValue(Result_1, 1));
382 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
383 MemOp[0] = LD->getMemOperand();
384 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
385 const SDValue Froms[] = { SDValue(LD, 0),
389 const SDValue Tos[] = { SDValue(Result_2, 0),
390 SDValue(Result_3, 0),
393 ReplaceUses(Froms, Tos, 3);
396 return SelectCode(LD);
400 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
404 SDValue Chain = LD->getChain();
405 EVT LoadedVT = LD->getMemoryVT();
406 SDValue Base = LD->getBasePtr();
407 SDValue Offset = LD->getOffset();
408 SDNode *OffsetNode = Offset.getNode();
409 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
410 SDValue N1 = LD->getOperand(1);
414 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
415 N1.getNode()->getValueType(0) == MVT::i32) {
416 const HexagonInstrInfo *TII = Subtarget->getInstrInfo();
417 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
418 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
419 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
420 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
421 MVT::i32, MVT::Other, Base,
422 TargetConstVal, Chain);
423 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
425 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
426 MVT::i64, MVT::Other,
428 SDValue(Result_1,0));
429 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
430 MemOp[0] = LD->getMemOperand();
431 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
432 const SDValue Froms[] = { SDValue(LD, 0),
436 const SDValue Tos[] = { SDValue(Result_3, 0),
437 SDValue(Result_1, 1),
440 ReplaceUses(Froms, Tos, 3);
444 // Generate an indirect load.
445 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
446 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
447 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
449 Base, TargetConst0, Chain);
450 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
452 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
453 MVT::i64, MVT::Other,
455 SDValue(Result_1,0));
456 // Add offset to base.
457 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
458 Base, TargetConstVal,
459 SDValue(Result_1, 1));
460 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
461 MemOp[0] = LD->getMemOperand();
462 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
463 const SDValue Froms[] = { SDValue(LD, 0),
467 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
468 SDValue(Result_4, 0), // New address.
471 ReplaceUses(Froms, Tos, 3);
475 return SelectCode(LD);
479 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
480 SDValue Chain = LD->getChain();
481 SDValue Base = LD->getBasePtr();
482 SDValue Offset = LD->getOffset();
483 SDNode *OffsetNode = Offset.getNode();
484 // Get the constant value.
485 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
486 EVT LoadedVT = LD->getMemoryVT();
489 // Check for zero ext loads.
490 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
492 // Figure out the opcode.
493 const HexagonInstrInfo *TII = Subtarget->getInstrInfo();
494 if (LoadedVT == MVT::i64) {
495 if (TII->isValidAutoIncImm(LoadedVT, Val))
496 Opcode = Hexagon::L2_loadrd_pi;
498 Opcode = Hexagon::L2_loadrd_io;
499 } else if (LoadedVT == MVT::i32) {
500 if (TII->isValidAutoIncImm(LoadedVT, Val))
501 Opcode = Hexagon::L2_loadri_pi;
503 Opcode = Hexagon::L2_loadri_io;
504 } else if (LoadedVT == MVT::i16) {
505 if (TII->isValidAutoIncImm(LoadedVT, Val))
506 Opcode = zextval ? Hexagon::L2_loadruh_pi : Hexagon::L2_loadrh_pi;
508 Opcode = zextval ? Hexagon::L2_loadruh_io : Hexagon::L2_loadrh_io;
509 } else if (LoadedVT == MVT::i8) {
510 if (TII->isValidAutoIncImm(LoadedVT, Val))
511 Opcode = zextval ? Hexagon::L2_loadrub_pi : Hexagon::L2_loadrb_pi;
513 Opcode = zextval ? Hexagon::L2_loadrub_io : Hexagon::L2_loadrb_io;
515 llvm_unreachable("unknown memory type");
517 // For zero ext i64 loads, we need to add combine instructions.
518 if (LD->getValueType(0) == MVT::i64 &&
519 LD->getExtensionType() == ISD::ZEXTLOAD) {
520 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
522 if (LD->getValueType(0) == MVT::i64 &&
523 LD->getExtensionType() == ISD::SEXTLOAD) {
524 // Handle sign ext i64 loads.
525 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
527 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
528 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
529 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
531 MVT::i32, MVT::Other, Base,
532 TargetConstVal, Chain);
533 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
534 MemOp[0] = LD->getMemOperand();
535 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
536 const SDValue Froms[] = { SDValue(LD, 0),
540 const SDValue Tos[] = { SDValue(Result, 0),
544 ReplaceUses(Froms, Tos, 3);
547 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
548 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
549 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
551 MVT::Other, Base, TargetConst0,
553 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::A2_addi, 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_1, 0),
564 SDValue(Result_2, 0),
567 ReplaceUses(Froms, Tos, 3);
573 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
576 LoadSDNode *LD = cast<LoadSDNode>(N);
577 ISD::MemIndexedMode AM = LD->getAddressingMode();
579 // Handle indexed loads.
580 if (AM != ISD::UNINDEXED) {
581 result = SelectIndexedLoad(LD, dl);
583 result = SelectCode(LD);
590 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
591 SDValue Chain = ST->getChain();
592 SDValue Base = ST->getBasePtr();
593 SDValue Offset = ST->getOffset();
594 SDValue Value = ST->getValue();
595 SDNode *OffsetNode = Offset.getNode();
596 // Get the constant value.
597 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
598 EVT StoredVT = ST->getMemoryVT();
600 // Offset value must be within representable range
601 // and must have correct alignment properties.
602 const HexagonInstrInfo *TII = Subtarget->getInstrInfo();
603 if (TII->isValidAutoIncImm(StoredVT, Val)) {
604 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
608 // Figure out the post inc version of opcode.
609 if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_pi;
610 else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_pi;
611 else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_pi;
612 else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_pi;
613 else llvm_unreachable("unknown memory type");
615 // Build post increment store.
616 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
618 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
619 MemOp[0] = ST->getMemOperand();
620 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
622 ReplaceUses(ST, Result);
623 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
627 // Note: Order of operands matches the def of instruction:
628 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
629 // and it differs for POST_ST* for instance.
630 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
634 // Figure out the opcode.
635 if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
636 else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
637 else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
638 else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
639 else llvm_unreachable("unknown memory type");
641 // Build regular store.
642 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
643 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
644 // Build splitted incriment instruction.
645 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
648 SDValue(Result_1, 0));
649 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
650 MemOp[0] = ST->getMemOperand();
651 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
653 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
654 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
659 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
661 StoreSDNode *ST = cast<StoreSDNode>(N);
662 ISD::MemIndexedMode AM = ST->getAddressingMode();
664 // Handle indexed stores.
665 if (AM != ISD::UNINDEXED) {
666 return SelectIndexedStore(ST, dl);
669 return SelectCode(ST);
672 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
676 // %conv.i = sext i32 %tmp1 to i64
677 // %conv2.i = sext i32 %add to i64
678 // %mul.i = mul nsw i64 %conv2.i, %conv.i
680 // --- match with the following ---
682 // %mul.i = mpy (%tmp1, %add)
685 if (N->getValueType(0) == MVT::i64) {
686 // Shifting a i64 signed multiply.
687 SDValue MulOp0 = N->getOperand(0);
688 SDValue MulOp1 = N->getOperand(1);
693 // Handle sign_extend and sextload.
694 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
695 SDValue Sext0 = MulOp0.getOperand(0);
696 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
697 return SelectCode(N);
701 } else if (MulOp0.getOpcode() == ISD::LOAD) {
702 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
703 if (LD->getMemoryVT() != MVT::i32 ||
704 LD->getExtensionType() != ISD::SEXTLOAD ||
705 LD->getAddressingMode() != ISD::UNINDEXED) {
706 return SelectCode(N);
709 SDValue Chain = LD->getChain();
710 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
711 OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
713 LD->getBasePtr(), TargetConst0,
716 return SelectCode(N);
719 // Same goes for the second operand.
720 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
721 SDValue Sext1 = MulOp1.getOperand(0);
722 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
723 return SelectCode(N);
727 } else if (MulOp1.getOpcode() == ISD::LOAD) {
728 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
729 if (LD->getMemoryVT() != MVT::i32 ||
730 LD->getExtensionType() != ISD::SEXTLOAD ||
731 LD->getAddressingMode() != ISD::UNINDEXED) {
732 return SelectCode(N);
735 SDValue Chain = LD->getChain();
736 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
737 OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
739 LD->getBasePtr(), TargetConst0,
742 return SelectCode(N);
745 // Generate a mpy instruction.
746 SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl, MVT::i64,
748 ReplaceUses(N, Result);
752 return SelectCode(N);
756 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
758 SDValue N0 = N->getOperand(0);
759 if (N0.getOpcode() == ISD::SETCC) {
760 SDValue N00 = N0.getOperand(0);
761 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
762 SDValue N000 = N00.getOperand(0);
763 SDValue N001 = N00.getOperand(1);
764 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
765 SDValue N01 = N0.getOperand(1);
766 SDValue N02 = N0.getOperand(2);
768 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
769 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
770 // IntRegs:i32:$src2)
771 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
772 // Pattern complexity = 9 cost = 1 size = 0.
773 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
774 SDValue N1 = N->getOperand(1);
776 SDValue N2 = N->getOperand(2);
778 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
779 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
780 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
782 SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_max, dl,
784 SDValue(SextNode, 0),
786 ReplaceUses(N, Result);
792 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
793 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
794 // IntRegs:i32:$src2)
795 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
796 // Pattern complexity = 9 cost = 1 size = 0.
797 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
798 SDValue N1 = N->getOperand(1);
800 SDValue N2 = N->getOperand(2);
802 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
803 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
804 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
806 SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_min, dl,
808 SDValue(SextNode, 0),
810 ReplaceUses(N, Result);
819 return SelectCode(N);
823 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
825 SDValue Shift = N->getOperand(0);
828 // %conv.i = sext i32 %tmp1 to i64
829 // %conv2.i = sext i32 %add to i64
830 // %mul.i = mul nsw i64 %conv2.i, %conv.i
831 // %shr5.i = lshr i64 %mul.i, 32
832 // %conv3.i = trunc i64 %shr5.i to i32
834 // --- match with the following ---
836 // %conv3.i = mpy (%tmp1, %add)
839 if (N->getValueType(0) == MVT::i32) {
841 if (Shift.getNode()->getValueType(0) == MVT::i64) {
842 // Trunc child is logical shift right.
843 if (Shift.getOpcode() != ISD::SRL) {
844 return SelectCode(N);
847 SDValue ShiftOp0 = Shift.getOperand(0);
848 SDValue ShiftOp1 = Shift.getOperand(1);
851 if (ShiftOp1.getOpcode() != ISD::Constant) {
852 return SelectCode(N);
856 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
857 if (ShiftConst != 32) {
858 return SelectCode(N);
861 // Shifting a i64 signed multiply
862 SDValue Mul = ShiftOp0;
863 if (Mul.getOpcode() != ISD::MUL) {
864 return SelectCode(N);
867 SDValue MulOp0 = Mul.getOperand(0);
868 SDValue MulOp1 = Mul.getOperand(1);
873 // Handle sign_extend and sextload
874 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
875 SDValue Sext0 = MulOp0.getOperand(0);
876 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
877 return SelectCode(N);
881 } else if (MulOp0.getOpcode() == ISD::LOAD) {
882 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
883 if (LD->getMemoryVT() != MVT::i32 ||
884 LD->getExtensionType() != ISD::SEXTLOAD ||
885 LD->getAddressingMode() != ISD::UNINDEXED) {
886 return SelectCode(N);
889 SDValue Chain = LD->getChain();
890 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
891 OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
894 TargetConst0, Chain), 0);
896 return SelectCode(N);
899 // Same goes for the second operand.
900 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
901 SDValue Sext1 = MulOp1.getOperand(0);
902 if (Sext1.getNode()->getValueType(0) != MVT::i32)
903 return SelectCode(N);
906 } else if (MulOp1.getOpcode() == ISD::LOAD) {
907 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
908 if (LD->getMemoryVT() != MVT::i32 ||
909 LD->getExtensionType() != ISD::SEXTLOAD ||
910 LD->getAddressingMode() != ISD::UNINDEXED) {
911 return SelectCode(N);
914 SDValue Chain = LD->getChain();
915 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
916 OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
919 TargetConst0, Chain), 0);
921 return SelectCode(N);
924 // Generate a mpy instruction.
925 SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_mpy_up, dl, MVT::i32,
927 ReplaceUses(N, Result);
932 return SelectCode(N);
936 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
938 if (N->getValueType(0) == MVT::i32) {
939 SDValue Shl_0 = N->getOperand(0);
940 SDValue Shl_1 = N->getOperand(1);
942 if (Shl_1.getOpcode() == ISD::Constant) {
943 if (Shl_0.getOpcode() == ISD::MUL) {
944 SDValue Mul_0 = Shl_0.getOperand(0); // Val
945 SDValue Mul_1 = Shl_0.getOperand(1); // Const
946 // RHS of mul is const.
947 if (Mul_1.getOpcode() == ISD::Constant) {
949 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
951 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
952 int32_t ValConst = MulConst << ShlConst;
953 SDValue Val = CurDAG->getTargetConstant(ValConst,
955 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
956 if (isInt<9>(CN->getSExtValue())) {
958 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
959 MVT::i32, Mul_0, Val);
960 ReplaceUses(N, Result);
965 } else if (Shl_0.getOpcode() == ISD::SUB) {
966 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
967 SDValue Sub_1 = Shl_0.getOperand(1); // Val
968 if (Sub_0.getOpcode() == ISD::Constant) {
970 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
972 if (Sub_1.getOpcode() == ISD::SHL) {
973 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
974 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
975 if (Shl2_1.getOpcode() == ISD::Constant) {
977 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
979 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
980 int32_t ValConst = 1 << (ShlConst+Shl2Const);
981 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
982 if (ConstantSDNode *CN =
983 dyn_cast<ConstantSDNode>(Val.getNode()))
984 if (isInt<9>(CN->getSExtValue())) {
986 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, MVT::i32,
988 ReplaceUses(N, Result);
998 return SelectCode(N);
1003 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1004 // result of the intrinsic is predicate); convert the zero_extend to
1005 // transfer instruction.
1007 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1008 // converted into a MUX as predicate registers defined as 1 bit in the
1009 // compiler. Architecture defines them as 8-bit registers.
1010 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1012 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1014 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1015 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1017 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1018 if (doesIntrinsicReturnPredicate(ID)) {
1019 // Now we need to differentiate target data types.
1020 if (N->getValueType(0) == MVT::i64) {
1021 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1022 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1023 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
1025 SDValue(IsIntrinsic, 0));
1026 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl,
1029 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
1030 MVT::i64, MVT::Other,
1031 SDValue(Result_2, 0),
1032 SDValue(Result_1, 0));
1033 ReplaceUses(N, Result_3);
1036 if (N->getValueType(0) == MVT::i32) {
1037 // Convert the zero_extend to Rs = Pd
1038 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
1040 SDValue(IsIntrinsic, 0));
1041 ReplaceUses(N, RsPd);
1044 llvm_unreachable("Unexpected value type");
1047 return SelectCode(N);
1051 // Checking for intrinsics which have predicate registers as operand(s)
1052 // and lowering to the actual intrinsic.
1054 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1055 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1058 case Intrinsic::hexagon_S2_vsplatrb:
1061 case Intrinsic::hexagon_S2_vsplatrh:
1065 return SelectCode(N);
1068 SDValue const &V = N->getOperand(1);
1070 if (isValueExtension(V, Bits, U)) {
1071 SDValue R = CurDAG->getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
1072 N->getOperand(0), U);
1073 return SelectCode(R.getNode());
1075 return SelectCode(N);
1079 // Map floating point constant values.
1081 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1083 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1084 APFloat APF = CN->getValueAPF();
1085 if (N->getValueType(0) == MVT::f32) {
1086 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1087 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1089 else if (N->getValueType(0) == MVT::f64) {
1090 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1091 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1094 return SelectCode(N);
1099 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1101 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1103 if (N->getValueType(0) == MVT::i1) {
1105 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1107 // Create the IntReg = 1 node.
1109 CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
1110 CurDAG->getTargetConstant(0, MVT::i32));
1113 SDNode* Pd = CurDAG->getMachineNode(Hexagon::C2_tfrrp, dl, MVT::i1,
1114 SDValue(IntRegTFR, 0));
1117 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::C2_not, dl, MVT::i1,
1121 Result = CurDAG->getMachineNode(Hexagon::C2_xor, dl, MVT::i1,
1122 SDValue(Pd, 0), SDValue(NotPd, 0));
1124 // We have just built:
1126 // Pd = xor(not(Pd), Pd)
1128 ReplaceUses(N, Result);
1133 return SelectCode(N);
1138 // Map add followed by a asr -> asr +=.
1140 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1142 if (N->getValueType(0) != MVT::i32) {
1143 return SelectCode(N);
1145 // Identify nodes of the form: add(asr(...)).
1146 SDNode* Src1 = N->getOperand(0).getNode();
1147 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1148 || Src1->getValueType(0) != MVT::i32) {
1149 return SelectCode(N);
1152 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1153 // Rd and Rd' are assigned to the same register
1154 SDNode* Result = CurDAG->getMachineNode(Hexagon::S2_asr_r_r_acc, dl, MVT::i32,
1156 Src1->getOperand(0),
1157 Src1->getOperand(1));
1158 ReplaceUses(N, Result);
1164 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1165 if (N->isMachineOpcode()) {
1167 return nullptr; // Already selected.
1171 switch (N->getOpcode()) {
1173 return SelectConstant(N);
1175 case ISD::ConstantFP:
1176 return SelectConstantFP(N);
1179 return SelectAdd(N);
1182 return SelectSHL(N);
1185 return SelectLoad(N);
1188 return SelectStore(N);
1191 return SelectSelect(N);
1194 return SelectTruncate(N);
1197 return SelectMul(N);
1199 case ISD::ZERO_EXTEND:
1200 return SelectZeroExtend(N);
1202 case ISD::INTRINSIC_WO_CHAIN:
1203 return SelectIntrinsicWOChain(N);
1206 return SelectCode(N);
1211 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1212 // to define these instructions.
1214 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1216 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1217 Addr.getOpcode() == ISD::TargetGlobalAddress)
1218 return false; // Direct calls.
1220 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1221 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1222 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1226 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1231 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1233 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1234 Addr.getOpcode() == ISD::TargetGlobalAddress)
1235 return false; // Direct calls.
1237 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1238 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1239 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1240 return (IsS11_0_Offset(Offset.getNode()));
1243 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1244 return (IsS11_0_Offset(Offset.getNode()));
1248 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1250 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1251 Addr.getOpcode() == ISD::TargetGlobalAddress)
1252 return false; // Direct calls.
1254 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1255 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1256 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1257 return (IsS11_1_Offset(Offset.getNode()));
1260 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1261 return (IsS11_1_Offset(Offset.getNode()));
1265 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1267 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1268 Addr.getOpcode() == ISD::TargetGlobalAddress)
1269 return false; // Direct calls.
1271 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1272 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1273 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1274 return (IsS11_2_Offset(Offset.getNode()));
1277 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1278 return (IsS11_2_Offset(Offset.getNode()));
1282 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1284 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1285 Addr.getOpcode() == ISD::TargetGlobalAddress)
1286 return false; // Direct calls.
1288 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1289 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1290 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1291 return (IsU6_0_Offset(Offset.getNode()));
1294 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1295 return (IsU6_0_Offset(Offset.getNode()));
1299 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1301 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1302 Addr.getOpcode() == ISD::TargetGlobalAddress)
1303 return false; // Direct calls.
1305 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1306 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1307 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1308 return (IsU6_1_Offset(Offset.getNode()));
1311 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1312 return (IsU6_1_Offset(Offset.getNode()));
1316 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1318 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1319 Addr.getOpcode() == ISD::TargetGlobalAddress)
1320 return false; // Direct calls.
1322 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1323 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1324 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1325 return (IsU6_2_Offset(Offset.getNode()));
1328 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1329 return (IsU6_2_Offset(Offset.getNode()));
1333 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1336 if (Addr.getOpcode() != ISD::ADD) {
1337 return(SelectADDRriS11_2(Addr, Base, Offset));
1340 return SelectADDRriS11_2(Addr, Base, Offset);
1344 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1346 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1347 Addr.getOpcode() == ISD::TargetGlobalAddress)
1348 return false; // Direct calls.
1350 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1351 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1352 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1353 return (IsS11_3_Offset(Offset.getNode()));
1356 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1357 return (IsS11_3_Offset(Offset.getNode()));
1360 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1362 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1363 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1364 Addr.getOpcode() == ISD::TargetGlobalAddress)
1365 return false; // Direct calls.
1367 if (Addr.getOpcode() == ISD::ADD) {
1368 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1369 if (isInt<13>(CN->getSExtValue()))
1370 return false; // Let the reg+imm pattern catch this!
1371 R1 = Addr.getOperand(0);
1372 R2 = Addr.getOperand(1);
1382 // Handle generic address case. It is accessed from inlined asm =m constraints,
1383 // which could have any kind of pointer.
1384 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1385 SDValue &Base, SDValue &Offset) {
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 if (Addr.getOpcode() == ISD::ADD) {
1397 Base = Addr.getOperand(0);
1398 Offset = Addr.getOperand(1);
1403 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1408 bool HexagonDAGToDAGISel::
1409 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1410 std::vector<SDValue> &OutOps) {
1413 switch (ConstraintCode) {
1414 case 'o': // Offsetable.
1415 case 'v': // Not offsetable.
1416 default: return true;
1417 case 'm': // Memory.
1418 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1423 OutOps.push_back(Op0);
1424 OutOps.push_back(Op1);
1428 //===--------------------------------------------------------------------===//
1429 // Return true if the non-GP-relative global address can be folded.
1430 //===--------------------------------------------------------------------===//
1431 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
1432 return foldGlobalAddressImpl(N, R, false);
1435 //===--------------------------------------------------------------------===//
1436 // Return true if the GP-relative global address can be folded.
1437 //===--------------------------------------------------------------------===//
1438 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
1439 return foldGlobalAddressImpl(N, R, true);
1442 //===--------------------------------------------------------------------===//
1443 // Fold offset of the global address if number of uses are below threshold.
1444 //===--------------------------------------------------------------------===//
1445 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
1446 bool ShouldLookForGP) {
1447 if (N.getOpcode() == ISD::ADD) {
1448 SDValue N0 = N.getOperand(0);
1449 SDValue N1 = N.getOperand(1);
1450 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
1451 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
1452 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
1453 GlobalAddressSDNode *GA =
1454 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
1457 (GA->getOpcode() == ISD::TargetGlobalAddress)) {
1458 if ((N0.getOpcode() == HexagonISD::CONST32) &&
1459 !hasNumUsesBelowThresGA(GA))
1461 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
1465 (uint64_t)Const->getSExtValue());
1473 bool HexagonDAGToDAGISel::SelectAddrFI(SDValue& N, SDValue &R) {
1474 if (N.getOpcode() != ISD::FrameIndex)
1476 FrameIndexSDNode *FX = cast<FrameIndexSDNode>(N);
1477 R = CurDAG->getTargetFrameIndex(FX->getIndex(), MVT::i32);
1481 inline bool HexagonDAGToDAGISel::SelectAddrGA(SDValue &N, SDValue &R) {
1482 return SelectGlobalAddress(N, R, false);
1485 inline bool HexagonDAGToDAGISel::SelectAddrGP(SDValue &N, SDValue &R) {
1486 return SelectGlobalAddress(N, R, true);
1489 bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R,
1491 switch (N.getOpcode()) {
1493 SDValue N0 = N.getOperand(0);
1494 SDValue N1 = N.getOperand(1);
1495 unsigned GAOpc = N0.getOpcode();
1496 if (UseGP && GAOpc != HexagonISD::CONST32_GP)
1498 if (!UseGP && GAOpc != HexagonISD::CONST32)
1500 if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1)) {
1501 SDValue Addr = N0.getOperand(0);
1502 if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Addr)) {
1503 if (GA->getOpcode() == ISD::TargetGlobalAddress) {
1504 uint64_t NewOff = GA->getOffset() + (uint64_t)Const->getSExtValue();
1505 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(Const),
1506 N.getValueType(), NewOff);
1513 case HexagonISD::CONST32:
1514 // The operand(0) of CONST32 is TargetGlobalAddress, which is what we
1515 // want in the instruction.
1517 R = N.getOperand(0);
1519 case HexagonISD::CONST32_GP:
1521 R = N.getOperand(0);
1530 bool HexagonDAGToDAGISel::isValueExtension(SDValue const &Val,
1531 unsigned FromBits, SDValue &Src) {
1532 unsigned Opc = Val.getOpcode();
1534 case ISD::SIGN_EXTEND:
1535 case ISD::ZERO_EXTEND:
1536 case ISD::ANY_EXTEND: {
1537 SDValue const &Op0 = Val.getOperand(0);
1538 EVT T = Op0.getValueType();
1539 if (T.isInteger() && T.getSizeInBits() == FromBits) {
1545 case ISD::SIGN_EXTEND_INREG:
1546 case ISD::AssertSext:
1547 case ISD::AssertZext:
1548 if (Val.getOperand(0).getValueType().isInteger()) {
1549 VTSDNode *T = cast<VTSDNode>(Val.getOperand(1));
1550 if (T->getVT().getSizeInBits() == FromBits) {
1551 Src = Val.getOperand(0);
1557 // Check if this is an AND with "FromBits" of lower bits set to 1.
1558 uint64_t FromMask = (1 << FromBits) - 1;
1559 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
1560 if (C->getZExtValue() == FromMask) {
1561 Src = Val.getOperand(1);
1565 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
1566 if (C->getZExtValue() == FromMask) {
1567 Src = Val.getOperand(0);
1575 // OR/XOR with the lower "FromBits" bits set to 0.
1576 uint64_t FromMask = (1 << FromBits) - 1;
1577 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
1578 if ((C->getZExtValue() & FromMask) == 0) {
1579 Src = Val.getOperand(1);
1583 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
1584 if ((C->getZExtValue() & FromMask) == 0) {
1585 Src = Val.getOperand(0);