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());
61 SDNode *Select(SDNode *N) override;
63 // Complex Pattern Selectors.
64 inline bool foldGlobalAddress(SDValue &N, SDValue &R);
65 inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
66 bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
67 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
68 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
69 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
70 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
71 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
72 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
73 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
74 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
75 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
76 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
78 // Complex Pattern Selectors.
79 inline bool SelectAddrGA(SDValue &N, SDValue &R);
80 inline bool SelectAddrGP(SDValue &N, SDValue &R);
81 bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP);
82 bool SelectAddrFI(SDValue &N, SDValue &R);
84 const char *getPassName() const override {
85 return "Hexagon DAG->DAG Pattern Instruction Selection";
88 bool runOnMachineFunction(MachineFunction &MF) override {
89 Subtarget = &MF.getSubtarget<HexagonSubtarget>();
90 return SelectionDAGISel::runOnMachineFunction(MF);
93 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
94 /// inline asm expressions.
95 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
97 std::vector<SDValue> &OutOps) override;
98 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
100 SDNode *SelectLoad(SDNode *N);
101 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl);
102 SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl);
103 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
105 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
107 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl);
108 SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl);
109 SDNode *SelectStore(SDNode *N);
110 SDNode *SelectSHL(SDNode *N);
111 SDNode *SelectSelect(SDNode *N);
112 SDNode *SelectTruncate(SDNode *N);
113 SDNode *SelectMul(SDNode *N);
114 SDNode *SelectZeroExtend(SDNode *N);
115 SDNode *SelectIntrinsicWOChain(SDNode *N);
116 SDNode *SelectIntrinsicWChain(SDNode *N);
117 SDNode *SelectConstant(SDNode *N);
118 SDNode *SelectConstantFP(SDNode *N);
119 SDNode *SelectAdd(SDNode *N);
121 // XformMskToBitPosU5Imm - Returns the bit position which
122 // the single bit 32 bit mask represents.
123 // Used in Clr and Set bit immediate memops.
124 SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
126 bitPos = Log2_32(Imm);
127 assert(bitPos >= 0 && bitPos < 32 &&
128 "Constant out of range for 32 BitPos Memops");
129 return CurDAG->getTargetConstant(bitPos, MVT::i32);
132 // XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
133 // mask represents. Used in Clr and Set bit immediate memops.
134 SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
135 return XformMskToBitPosU5Imm(Imm);
138 // XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
139 // mask represents. Used in Clr and Set bit immediate memops.
140 SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
141 return XformMskToBitPosU5Imm(Imm);
144 // Return true if there is exactly one bit set in V, i.e., if V is one of the
145 // following integers: 2^0, 2^1, ..., 2^31.
146 bool ImmIsSingleBit(uint32_t v) const {
147 return isPowerOf2_32(v);
150 // XformM5ToU5Imm - Return a target constant with the specified value, of type
151 // i32 where the negative literal is transformed into a positive literal for
153 inline SDValue XformM5ToU5Imm(signed Imm) {
154 assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
155 return CurDAG->getTargetConstant( - Imm, MVT::i32);
159 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
160 // [1..128], used in cmpb.gtu instructions.
161 inline SDValue XformU7ToU7M1Imm(signed Imm) {
162 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
163 return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
166 // XformS8ToS8M1Imm - Return a target constant decremented by 1.
167 inline SDValue XformSToSM1Imm(signed Imm) {
168 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
171 // XformU8ToU8M1Imm - Return a target constant decremented by 1.
172 inline SDValue XformUToUM1Imm(unsigned Imm) {
173 assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
174 return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
177 // XformSToSM2Imm - Return a target constant decremented by 2.
178 inline SDValue XformSToSM2Imm(unsigned Imm) {
179 return CurDAG->getTargetConstant(Imm - 2, MVT::i32);
182 // XformSToSM3Imm - Return a target constant decremented by 3.
183 inline SDValue XformSToSM3Imm(unsigned Imm) {
184 return CurDAG->getTargetConstant(Imm - 3, MVT::i32);
187 // Include the pieces autogenerated from the target description.
188 #include "HexagonGenDAGISel.inc"
191 bool isValueExtension(SDValue const &Val, unsigned FromBits, SDValue &Src);
193 } // end anonymous namespace
196 /// createHexagonISelDag - This pass converts a legalized DAG into a
197 /// Hexagon-specific DAG, ready for instruction scheduling.
199 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM,
200 CodeGenOpt::Level OptLevel) {
201 return new HexagonDAGToDAGISel(TM, OptLevel);
204 static void initializePassOnce(PassRegistry &Registry) {
205 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
206 PassInfo *PI = new PassInfo(Name, "hexagon-isel",
207 &SelectionDAGISel::ID, nullptr, false, false);
208 Registry.registerPass(*PI, true);
211 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
212 CALL_ONCE_INITIALIZATION(initializePassOnce)
216 static bool IsS11_0_Offset(SDNode * S) {
217 ConstantSDNode *N = cast<ConstantSDNode>(S);
219 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
221 int64_t v = (int64_t)N->getSExtValue();
226 static bool IsS11_1_Offset(SDNode * S) {
227 ConstantSDNode *N = cast<ConstantSDNode>(S);
229 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
231 int64_t v = (int64_t)N->getSExtValue();
232 return isShiftedInt<11,1>(v);
236 static bool IsS11_2_Offset(SDNode * S) {
237 ConstantSDNode *N = cast<ConstantSDNode>(S);
239 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
241 int64_t v = (int64_t)N->getSExtValue();
242 return isShiftedInt<11,2>(v);
246 static bool IsS11_3_Offset(SDNode * S) {
247 ConstantSDNode *N = cast<ConstantSDNode>(S);
249 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
251 int64_t v = (int64_t)N->getSExtValue();
252 return isShiftedInt<11,3>(v);
256 static bool IsU6_0_Offset(SDNode * S) {
257 ConstantSDNode *N = cast<ConstantSDNode>(S);
259 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
261 int64_t v = (int64_t)N->getSExtValue();
266 static bool IsU6_1_Offset(SDNode * S) {
267 ConstantSDNode *N = cast<ConstantSDNode>(S);
269 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
271 int64_t v = (int64_t)N->getSExtValue();
272 return isShiftedUInt<6,1>(v);
276 static bool IsU6_2_Offset(SDNode * S) {
277 ConstantSDNode *N = cast<ConstantSDNode>(S);
279 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
281 int64_t v = (int64_t)N->getSExtValue();
282 return isShiftedUInt<6,2>(v);
286 // Intrinsics that return a a predicate.
287 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
292 case Intrinsic::hexagon_C2_cmpeq:
293 case Intrinsic::hexagon_C2_cmpgt:
294 case Intrinsic::hexagon_C2_cmpgtu:
295 case Intrinsic::hexagon_C2_cmpgtup:
296 case Intrinsic::hexagon_C2_cmpgtp:
297 case Intrinsic::hexagon_C2_cmpeqp:
298 case Intrinsic::hexagon_C2_bitsset:
299 case Intrinsic::hexagon_C2_bitsclr:
300 case Intrinsic::hexagon_C2_cmpeqi:
301 case Intrinsic::hexagon_C2_cmpgti:
302 case Intrinsic::hexagon_C2_cmpgtui:
303 case Intrinsic::hexagon_C2_cmpgei:
304 case Intrinsic::hexagon_C2_cmpgeui:
305 case Intrinsic::hexagon_C2_cmplt:
306 case Intrinsic::hexagon_C2_cmpltu:
307 case Intrinsic::hexagon_C2_bitsclri:
308 case Intrinsic::hexagon_C2_and:
309 case Intrinsic::hexagon_C2_or:
310 case Intrinsic::hexagon_C2_xor:
311 case Intrinsic::hexagon_C2_andn:
312 case Intrinsic::hexagon_C2_not:
313 case Intrinsic::hexagon_C2_orn:
314 case Intrinsic::hexagon_C2_pxfer_map:
315 case Intrinsic::hexagon_C2_any8:
316 case Intrinsic::hexagon_C2_all8:
317 case Intrinsic::hexagon_A2_vcmpbeq:
318 case Intrinsic::hexagon_A2_vcmpbgtu:
319 case Intrinsic::hexagon_A2_vcmpheq:
320 case Intrinsic::hexagon_A2_vcmphgt:
321 case Intrinsic::hexagon_A2_vcmphgtu:
322 case Intrinsic::hexagon_A2_vcmpweq:
323 case Intrinsic::hexagon_A2_vcmpwgt:
324 case Intrinsic::hexagon_A2_vcmpwgtu:
325 case Intrinsic::hexagon_C2_tfrrp:
326 case Intrinsic::hexagon_S2_tstbit_i:
327 case Intrinsic::hexagon_S2_tstbit_r:
333 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
337 SDValue Chain = LD->getChain();
338 EVT LoadedVT = LD->getMemoryVT();
339 SDValue Base = LD->getBasePtr();
340 SDValue Offset = LD->getOffset();
341 SDNode *OffsetNode = Offset.getNode();
342 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
343 SDValue N1 = LD->getOperand(1);
347 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
348 N1.getNode()->getValueType(0) == MVT::i32) {
349 const HexagonInstrInfo *TII = Subtarget->getInstrInfo();
350 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
351 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
352 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
353 MVT::Other, Base, TargetConst,
355 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64,
356 SDValue(Result_1, 0));
357 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
358 MemOp[0] = LD->getMemOperand();
359 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
360 const SDValue Froms[] = { SDValue(LD, 0),
364 const SDValue Tos[] = { SDValue(Result_2, 0),
365 SDValue(Result_1, 1),
368 ReplaceUses(Froms, Tos, 3);
371 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
372 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
373 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
374 MVT::Other, Base, TargetConst0,
376 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl,
377 MVT::i64, SDValue(Result_1, 0));
378 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::A2_addi, dl,
379 MVT::i32, Base, TargetConstVal,
380 SDValue(Result_1, 1));
381 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
382 MemOp[0] = LD->getMemOperand();
383 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
384 const SDValue Froms[] = { SDValue(LD, 0),
388 const SDValue Tos[] = { SDValue(Result_2, 0),
389 SDValue(Result_3, 0),
392 ReplaceUses(Froms, Tos, 3);
395 return SelectCode(LD);
399 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
403 SDValue Chain = LD->getChain();
404 EVT LoadedVT = LD->getMemoryVT();
405 SDValue Base = LD->getBasePtr();
406 SDValue Offset = LD->getOffset();
407 SDNode *OffsetNode = Offset.getNode();
408 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
409 SDValue N1 = LD->getOperand(1);
413 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
414 N1.getNode()->getValueType(0) == MVT::i32) {
415 const HexagonInstrInfo *TII = Subtarget->getInstrInfo();
416 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
417 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
418 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
419 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
420 MVT::i32, MVT::Other, Base,
421 TargetConstVal, Chain);
422 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
424 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
425 MVT::i64, MVT::Other,
427 SDValue(Result_1,0));
428 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
429 MemOp[0] = LD->getMemOperand();
430 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
431 const SDValue Froms[] = { SDValue(LD, 0),
435 const SDValue Tos[] = { SDValue(Result_3, 0),
436 SDValue(Result_1, 1),
439 ReplaceUses(Froms, Tos, 3);
443 // Generate an indirect load.
444 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
445 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
446 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
448 Base, TargetConst0, Chain);
449 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
451 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
452 MVT::i64, MVT::Other,
454 SDValue(Result_1,0));
455 // Add offset to base.
456 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
457 Base, TargetConstVal,
458 SDValue(Result_1, 1));
459 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
460 MemOp[0] = LD->getMemOperand();
461 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
462 const SDValue Froms[] = { SDValue(LD, 0),
466 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
467 SDValue(Result_4, 0), // New address.
470 ReplaceUses(Froms, Tos, 3);
474 return SelectCode(LD);
478 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
479 SDValue Chain = LD->getChain();
480 SDValue Base = LD->getBasePtr();
481 SDValue Offset = LD->getOffset();
482 SDNode *OffsetNode = Offset.getNode();
483 // Get the constant value.
484 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
485 EVT LoadedVT = LD->getMemoryVT();
488 // Check for zero ext loads.
489 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
491 // Figure out the opcode.
492 const HexagonInstrInfo *TII = Subtarget->getInstrInfo();
493 if (LoadedVT == MVT::i64) {
494 if (TII->isValidAutoIncImm(LoadedVT, Val))
495 Opcode = Hexagon::L2_loadrd_pi;
497 Opcode = Hexagon::L2_loadrd_io;
498 } else if (LoadedVT == MVT::i32) {
499 if (TII->isValidAutoIncImm(LoadedVT, Val))
500 Opcode = Hexagon::L2_loadri_pi;
502 Opcode = Hexagon::L2_loadri_io;
503 } else if (LoadedVT == MVT::i16) {
504 if (TII->isValidAutoIncImm(LoadedVT, Val))
505 Opcode = zextval ? Hexagon::L2_loadruh_pi : Hexagon::L2_loadrh_pi;
507 Opcode = zextval ? Hexagon::L2_loadruh_io : Hexagon::L2_loadrh_io;
508 } else if (LoadedVT == MVT::i8) {
509 if (TII->isValidAutoIncImm(LoadedVT, Val))
510 Opcode = zextval ? Hexagon::L2_loadrub_pi : Hexagon::L2_loadrb_pi;
512 Opcode = zextval ? Hexagon::L2_loadrub_io : Hexagon::L2_loadrb_io;
514 llvm_unreachable("unknown memory type");
516 // For zero ext i64 loads, we need to add combine instructions.
517 if (LD->getValueType(0) == MVT::i64 &&
518 LD->getExtensionType() == ISD::ZEXTLOAD) {
519 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
521 if (LD->getValueType(0) == MVT::i64 &&
522 LD->getExtensionType() == ISD::SEXTLOAD) {
523 // Handle sign ext i64 loads.
524 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
526 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
527 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
528 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
530 MVT::i32, MVT::Other, Base,
531 TargetConstVal, Chain);
532 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
533 MemOp[0] = LD->getMemOperand();
534 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
535 const SDValue Froms[] = { SDValue(LD, 0),
539 const SDValue Tos[] = { SDValue(Result, 0),
543 ReplaceUses(Froms, Tos, 3);
546 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
547 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
548 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
550 MVT::Other, Base, TargetConst0,
552 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
553 Base, TargetConstVal,
554 SDValue(Result_1, 1));
555 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
556 MemOp[0] = LD->getMemOperand();
557 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
558 const SDValue Froms[] = { SDValue(LD, 0),
562 const SDValue Tos[] = { SDValue(Result_1, 0),
563 SDValue(Result_2, 0),
566 ReplaceUses(Froms, Tos, 3);
572 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
575 LoadSDNode *LD = cast<LoadSDNode>(N);
576 ISD::MemIndexedMode AM = LD->getAddressingMode();
578 // Handle indexed loads.
579 if (AM != ISD::UNINDEXED) {
580 result = SelectIndexedLoad(LD, dl);
582 result = SelectCode(LD);
589 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
590 SDValue Chain = ST->getChain();
591 SDValue Base = ST->getBasePtr();
592 SDValue Offset = ST->getOffset();
593 SDValue Value = ST->getValue();
594 SDNode *OffsetNode = Offset.getNode();
595 // Get the constant value.
596 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
597 EVT StoredVT = ST->getMemoryVT();
599 // Offset value must be within representable range
600 // and must have correct alignment properties.
601 const HexagonInstrInfo *TII = Subtarget->getInstrInfo();
602 if (TII->isValidAutoIncImm(StoredVT, Val)) {
603 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
607 // Figure out the post inc version of opcode.
608 if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_pi;
609 else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_pi;
610 else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_pi;
611 else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_pi;
612 else llvm_unreachable("unknown memory type");
614 // Build post increment store.
615 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
617 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
618 MemOp[0] = ST->getMemOperand();
619 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
621 ReplaceUses(ST, Result);
622 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
626 // Note: Order of operands matches the def of instruction:
627 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
628 // and it differs for POST_ST* for instance.
629 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
633 // Figure out the opcode.
634 if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
635 else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
636 else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
637 else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
638 else llvm_unreachable("unknown memory type");
640 // Build regular store.
641 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
642 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
643 // Build splitted incriment instruction.
644 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
647 SDValue(Result_1, 0));
648 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
649 MemOp[0] = ST->getMemOperand();
650 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
652 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
653 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
658 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
660 StoreSDNode *ST = cast<StoreSDNode>(N);
661 ISD::MemIndexedMode AM = ST->getAddressingMode();
663 // Handle indexed stores.
664 if (AM != ISD::UNINDEXED) {
665 return SelectIndexedStore(ST, dl);
668 return SelectCode(ST);
671 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
675 // %conv.i = sext i32 %tmp1 to i64
676 // %conv2.i = sext i32 %add to i64
677 // %mul.i = mul nsw i64 %conv2.i, %conv.i
679 // --- match with the following ---
681 // %mul.i = mpy (%tmp1, %add)
684 if (N->getValueType(0) == MVT::i64) {
685 // Shifting a i64 signed multiply.
686 SDValue MulOp0 = N->getOperand(0);
687 SDValue MulOp1 = N->getOperand(1);
692 // Handle sign_extend and sextload.
693 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
694 SDValue Sext0 = MulOp0.getOperand(0);
695 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
696 return SelectCode(N);
700 } else if (MulOp0.getOpcode() == ISD::LOAD) {
701 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
702 if (LD->getMemoryVT() != MVT::i32 ||
703 LD->getExtensionType() != ISD::SEXTLOAD ||
704 LD->getAddressingMode() != ISD::UNINDEXED) {
705 return SelectCode(N);
708 SDValue Chain = LD->getChain();
709 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
710 OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
712 LD->getBasePtr(), TargetConst0,
715 return SelectCode(N);
718 // Same goes for the second operand.
719 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
720 SDValue Sext1 = MulOp1.getOperand(0);
721 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
722 return SelectCode(N);
726 } else if (MulOp1.getOpcode() == ISD::LOAD) {
727 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
728 if (LD->getMemoryVT() != MVT::i32 ||
729 LD->getExtensionType() != ISD::SEXTLOAD ||
730 LD->getAddressingMode() != ISD::UNINDEXED) {
731 return SelectCode(N);
734 SDValue Chain = LD->getChain();
735 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
736 OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
738 LD->getBasePtr(), TargetConst0,
741 return SelectCode(N);
744 // Generate a mpy instruction.
745 SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl, MVT::i64,
747 ReplaceUses(N, Result);
751 return SelectCode(N);
755 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
757 SDValue N0 = N->getOperand(0);
758 if (N0.getOpcode() == ISD::SETCC) {
759 SDValue N00 = N0.getOperand(0);
760 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
761 SDValue N000 = N00.getOperand(0);
762 SDValue N001 = N00.getOperand(1);
763 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
764 SDValue N01 = N0.getOperand(1);
765 SDValue N02 = N0.getOperand(2);
767 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
768 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
769 // IntRegs:i32:$src2)
770 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
771 // Pattern complexity = 9 cost = 1 size = 0.
772 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
773 SDValue N1 = N->getOperand(1);
775 SDValue N2 = N->getOperand(2);
777 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
778 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
779 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
781 SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_max, dl,
783 SDValue(SextNode, 0),
785 ReplaceUses(N, Result);
791 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
792 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
793 // IntRegs:i32:$src2)
794 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
795 // Pattern complexity = 9 cost = 1 size = 0.
796 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
797 SDValue N1 = N->getOperand(1);
799 SDValue N2 = N->getOperand(2);
801 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
802 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
803 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
805 SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_min, dl,
807 SDValue(SextNode, 0),
809 ReplaceUses(N, Result);
818 return SelectCode(N);
822 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
824 SDValue Shift = N->getOperand(0);
827 // %conv.i = sext i32 %tmp1 to i64
828 // %conv2.i = sext i32 %add to i64
829 // %mul.i = mul nsw i64 %conv2.i, %conv.i
830 // %shr5.i = lshr i64 %mul.i, 32
831 // %conv3.i = trunc i64 %shr5.i to i32
833 // --- match with the following ---
835 // %conv3.i = mpy (%tmp1, %add)
838 if (N->getValueType(0) == MVT::i32) {
840 if (Shift.getNode()->getValueType(0) == MVT::i64) {
841 // Trunc child is logical shift right.
842 if (Shift.getOpcode() != ISD::SRL) {
843 return SelectCode(N);
846 SDValue ShiftOp0 = Shift.getOperand(0);
847 SDValue ShiftOp1 = Shift.getOperand(1);
850 if (ShiftOp1.getOpcode() != ISD::Constant) {
851 return SelectCode(N);
855 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
856 if (ShiftConst != 32) {
857 return SelectCode(N);
860 // Shifting a i64 signed multiply
861 SDValue Mul = ShiftOp0;
862 if (Mul.getOpcode() != ISD::MUL) {
863 return SelectCode(N);
866 SDValue MulOp0 = Mul.getOperand(0);
867 SDValue MulOp1 = Mul.getOperand(1);
872 // Handle sign_extend and sextload
873 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
874 SDValue Sext0 = MulOp0.getOperand(0);
875 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
876 return SelectCode(N);
880 } else if (MulOp0.getOpcode() == ISD::LOAD) {
881 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
882 if (LD->getMemoryVT() != MVT::i32 ||
883 LD->getExtensionType() != ISD::SEXTLOAD ||
884 LD->getAddressingMode() != ISD::UNINDEXED) {
885 return SelectCode(N);
888 SDValue Chain = LD->getChain();
889 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
890 OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
893 TargetConst0, Chain), 0);
895 return SelectCode(N);
898 // Same goes for the second operand.
899 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
900 SDValue Sext1 = MulOp1.getOperand(0);
901 if (Sext1.getNode()->getValueType(0) != MVT::i32)
902 return SelectCode(N);
905 } else if (MulOp1.getOpcode() == ISD::LOAD) {
906 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
907 if (LD->getMemoryVT() != MVT::i32 ||
908 LD->getExtensionType() != ISD::SEXTLOAD ||
909 LD->getAddressingMode() != ISD::UNINDEXED) {
910 return SelectCode(N);
913 SDValue Chain = LD->getChain();
914 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
915 OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
918 TargetConst0, Chain), 0);
920 return SelectCode(N);
923 // Generate a mpy instruction.
924 SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_mpy_up, dl, MVT::i32,
926 ReplaceUses(N, Result);
931 return SelectCode(N);
935 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
937 if (N->getValueType(0) == MVT::i32) {
938 SDValue Shl_0 = N->getOperand(0);
939 SDValue Shl_1 = N->getOperand(1);
941 if (Shl_1.getOpcode() == ISD::Constant) {
942 if (Shl_0.getOpcode() == ISD::MUL) {
943 SDValue Mul_0 = Shl_0.getOperand(0); // Val
944 SDValue Mul_1 = Shl_0.getOperand(1); // Const
945 // RHS of mul is const.
946 if (Mul_1.getOpcode() == ISD::Constant) {
948 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
950 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
951 int32_t ValConst = MulConst << ShlConst;
952 SDValue Val = CurDAG->getTargetConstant(ValConst,
954 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
955 if (isInt<9>(CN->getSExtValue())) {
957 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
958 MVT::i32, Mul_0, Val);
959 ReplaceUses(N, Result);
964 } else if (Shl_0.getOpcode() == ISD::SUB) {
965 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
966 SDValue Sub_1 = Shl_0.getOperand(1); // Val
967 if (Sub_0.getOpcode() == ISD::Constant) {
969 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
971 if (Sub_1.getOpcode() == ISD::SHL) {
972 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
973 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
974 if (Shl2_1.getOpcode() == ISD::Constant) {
976 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
978 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
979 int32_t ValConst = 1 << (ShlConst+Shl2Const);
980 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
981 if (ConstantSDNode *CN =
982 dyn_cast<ConstantSDNode>(Val.getNode()))
983 if (isInt<9>(CN->getSExtValue())) {
985 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, MVT::i32,
987 ReplaceUses(N, Result);
997 return SelectCode(N);
1002 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1003 // result of the intrinsic is predicate); convert the zero_extend to
1004 // transfer instruction.
1006 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1007 // converted into a MUX as predicate registers defined as 1 bit in the
1008 // compiler. Architecture defines them as 8-bit registers.
1009 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1011 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1013 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1014 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1016 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1017 if (doesIntrinsicReturnPredicate(ID)) {
1018 // Now we need to differentiate target data types.
1019 if (N->getValueType(0) == MVT::i64) {
1020 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1021 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1022 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
1024 SDValue(IsIntrinsic, 0));
1025 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl,
1028 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
1029 MVT::i64, MVT::Other,
1030 SDValue(Result_2, 0),
1031 SDValue(Result_1, 0));
1032 ReplaceUses(N, Result_3);
1035 if (N->getValueType(0) == MVT::i32) {
1036 // Convert the zero_extend to Rs = Pd
1037 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
1039 SDValue(IsIntrinsic, 0));
1040 ReplaceUses(N, RsPd);
1043 llvm_unreachable("Unexpected value type");
1046 return SelectCode(N);
1050 // Checking for intrinsics which have predicate registers as operand(s)
1051 // and lowering to the actual intrinsic.
1053 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1054 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1057 case Intrinsic::hexagon_S2_vsplatrb:
1060 case Intrinsic::hexagon_S2_vsplatrh:
1064 return SelectCode(N);
1067 SDValue const &V = N->getOperand(1);
1069 if (isValueExtension(V, Bits, U)) {
1070 SDValue R = CurDAG->getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
1071 N->getOperand(0), U);
1072 return SelectCode(R.getNode());
1074 return SelectCode(N);
1078 // Map floating point constant values.
1080 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1082 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1083 APFloat APF = CN->getValueAPF();
1084 if (N->getValueType(0) == MVT::f32) {
1085 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1086 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1088 else if (N->getValueType(0) == MVT::f64) {
1089 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1090 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1093 return SelectCode(N);
1098 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1100 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1102 if (N->getValueType(0) == MVT::i1) {
1104 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1106 // Create the IntReg = 1 node.
1108 CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
1109 CurDAG->getTargetConstant(0, MVT::i32));
1112 SDNode* Pd = CurDAG->getMachineNode(Hexagon::C2_tfrrp, dl, MVT::i1,
1113 SDValue(IntRegTFR, 0));
1116 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::C2_not, dl, MVT::i1,
1120 Result = CurDAG->getMachineNode(Hexagon::C2_xor, dl, MVT::i1,
1121 SDValue(Pd, 0), SDValue(NotPd, 0));
1123 // We have just built:
1125 // Pd = xor(not(Pd), Pd)
1127 ReplaceUses(N, Result);
1132 return SelectCode(N);
1137 // Map add followed by a asr -> asr +=.
1139 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1141 if (N->getValueType(0) != MVT::i32) {
1142 return SelectCode(N);
1144 // Identify nodes of the form: add(asr(...)).
1145 SDNode* Src1 = N->getOperand(0).getNode();
1146 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1147 || Src1->getValueType(0) != MVT::i32) {
1148 return SelectCode(N);
1151 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1152 // Rd and Rd' are assigned to the same register
1153 SDNode* Result = CurDAG->getMachineNode(Hexagon::S2_asr_r_r_acc, dl, MVT::i32,
1155 Src1->getOperand(0),
1156 Src1->getOperand(1));
1157 ReplaceUses(N, Result);
1163 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1164 if (N->isMachineOpcode()) {
1166 return nullptr; // Already selected.
1170 switch (N->getOpcode()) {
1172 return SelectConstant(N);
1174 case ISD::ConstantFP:
1175 return SelectConstantFP(N);
1178 return SelectAdd(N);
1181 return SelectSHL(N);
1184 return SelectLoad(N);
1187 return SelectStore(N);
1190 return SelectSelect(N);
1193 return SelectTruncate(N);
1196 return SelectMul(N);
1198 case ISD::ZERO_EXTEND:
1199 return SelectZeroExtend(N);
1201 case ISD::INTRINSIC_WO_CHAIN:
1202 return SelectIntrinsicWOChain(N);
1205 return SelectCode(N);
1210 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1211 // to define these instructions.
1213 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1215 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1216 Addr.getOpcode() == ISD::TargetGlobalAddress)
1217 return false; // Direct calls.
1219 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1220 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1221 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1225 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1230 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1232 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1233 Addr.getOpcode() == ISD::TargetGlobalAddress)
1234 return false; // Direct calls.
1236 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1237 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1238 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1239 return (IsS11_0_Offset(Offset.getNode()));
1242 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1243 return (IsS11_0_Offset(Offset.getNode()));
1247 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1249 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1250 Addr.getOpcode() == ISD::TargetGlobalAddress)
1251 return false; // Direct calls.
1253 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1254 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1255 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1256 return (IsS11_1_Offset(Offset.getNode()));
1259 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1260 return (IsS11_1_Offset(Offset.getNode()));
1264 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1266 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1267 Addr.getOpcode() == ISD::TargetGlobalAddress)
1268 return false; // Direct calls.
1270 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1271 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1272 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1273 return (IsS11_2_Offset(Offset.getNode()));
1276 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1277 return (IsS11_2_Offset(Offset.getNode()));
1281 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1283 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1284 Addr.getOpcode() == ISD::TargetGlobalAddress)
1285 return false; // Direct calls.
1287 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1288 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1289 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1290 return (IsU6_0_Offset(Offset.getNode()));
1293 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1294 return (IsU6_0_Offset(Offset.getNode()));
1298 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1300 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1301 Addr.getOpcode() == ISD::TargetGlobalAddress)
1302 return false; // Direct calls.
1304 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1305 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1306 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1307 return (IsU6_1_Offset(Offset.getNode()));
1310 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1311 return (IsU6_1_Offset(Offset.getNode()));
1315 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1317 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1318 Addr.getOpcode() == ISD::TargetGlobalAddress)
1319 return false; // Direct calls.
1321 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1322 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1323 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1324 return (IsU6_2_Offset(Offset.getNode()));
1327 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1328 return (IsU6_2_Offset(Offset.getNode()));
1332 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1335 if (Addr.getOpcode() != ISD::ADD) {
1336 return(SelectADDRriS11_2(Addr, Base, Offset));
1339 return SelectADDRriS11_2(Addr, Base, Offset);
1343 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1345 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1346 Addr.getOpcode() == ISD::TargetGlobalAddress)
1347 return false; // Direct calls.
1349 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1350 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1351 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1352 return (IsS11_3_Offset(Offset.getNode()));
1355 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1356 return (IsS11_3_Offset(Offset.getNode()));
1359 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1361 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1362 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1363 Addr.getOpcode() == ISD::TargetGlobalAddress)
1364 return false; // Direct calls.
1366 if (Addr.getOpcode() == ISD::ADD) {
1367 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1368 if (isInt<13>(CN->getSExtValue()))
1369 return false; // Let the reg+imm pattern catch this!
1370 R1 = Addr.getOperand(0);
1371 R2 = Addr.getOperand(1);
1381 // Handle generic address case. It is accessed from inlined asm =m constraints,
1382 // which could have any kind of pointer.
1383 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1384 SDValue &Base, SDValue &Offset) {
1385 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1386 Addr.getOpcode() == ISD::TargetGlobalAddress)
1387 return false; // Direct calls.
1389 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1390 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1391 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1395 if (Addr.getOpcode() == ISD::ADD) {
1396 Base = Addr.getOperand(0);
1397 Offset = Addr.getOperand(1);
1402 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1407 bool HexagonDAGToDAGISel::
1408 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1409 std::vector<SDValue> &OutOps) {
1412 switch (ConstraintCode) {
1413 case 'o': // Offsetable.
1414 case 'v': // Not offsetable.
1415 default: return true;
1416 case 'm': // Memory.
1417 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1422 OutOps.push_back(Op0);
1423 OutOps.push_back(Op1);
1427 //===--------------------------------------------------------------------===//
1428 // Return true if the non-GP-relative global address can be folded.
1429 //===--------------------------------------------------------------------===//
1430 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
1431 return foldGlobalAddressImpl(N, R, false);
1434 //===--------------------------------------------------------------------===//
1435 // Return true if the GP-relative global address can be folded.
1436 //===--------------------------------------------------------------------===//
1437 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
1438 return foldGlobalAddressImpl(N, R, true);
1441 //===--------------------------------------------------------------------===//
1442 // Fold offset of the global address if number of uses are below threshold.
1443 //===--------------------------------------------------------------------===//
1444 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
1445 bool ShouldLookForGP) {
1446 if (N.getOpcode() == ISD::ADD) {
1447 SDValue N0 = N.getOperand(0);
1448 SDValue N1 = N.getOperand(1);
1449 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
1450 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
1451 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
1452 GlobalAddressSDNode *GA =
1453 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
1456 (GA->getOpcode() == ISD::TargetGlobalAddress)) {
1457 if (N0.getOpcode() == HexagonISD::CONST32)
1459 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
1463 (uint64_t)Const->getSExtValue());
1471 bool HexagonDAGToDAGISel::SelectAddrFI(SDValue& N, SDValue &R) {
1472 if (N.getOpcode() != ISD::FrameIndex)
1474 FrameIndexSDNode *FX = cast<FrameIndexSDNode>(N);
1475 R = CurDAG->getTargetFrameIndex(FX->getIndex(), MVT::i32);
1479 inline bool HexagonDAGToDAGISel::SelectAddrGA(SDValue &N, SDValue &R) {
1480 return SelectGlobalAddress(N, R, false);
1483 inline bool HexagonDAGToDAGISel::SelectAddrGP(SDValue &N, SDValue &R) {
1484 return SelectGlobalAddress(N, R, true);
1487 bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R,
1489 switch (N.getOpcode()) {
1491 SDValue N0 = N.getOperand(0);
1492 SDValue N1 = N.getOperand(1);
1493 unsigned GAOpc = N0.getOpcode();
1494 if (UseGP && GAOpc != HexagonISD::CONST32_GP)
1496 if (!UseGP && GAOpc != HexagonISD::CONST32)
1498 if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1)) {
1499 SDValue Addr = N0.getOperand(0);
1500 if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Addr)) {
1501 if (GA->getOpcode() == ISD::TargetGlobalAddress) {
1502 uint64_t NewOff = GA->getOffset() + (uint64_t)Const->getSExtValue();
1503 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(Const),
1504 N.getValueType(), NewOff);
1511 case HexagonISD::CONST32:
1512 // The operand(0) of CONST32 is TargetGlobalAddress, which is what we
1513 // want in the instruction.
1515 R = N.getOperand(0);
1517 case HexagonISD::CONST32_GP:
1519 R = N.getOperand(0);
1528 bool HexagonDAGToDAGISel::isValueExtension(SDValue const &Val,
1529 unsigned FromBits, SDValue &Src) {
1530 unsigned Opc = Val.getOpcode();
1532 case ISD::SIGN_EXTEND:
1533 case ISD::ZERO_EXTEND:
1534 case ISD::ANY_EXTEND: {
1535 SDValue const &Op0 = Val.getOperand(0);
1536 EVT T = Op0.getValueType();
1537 if (T.isInteger() && T.getSizeInBits() == FromBits) {
1543 case ISD::SIGN_EXTEND_INREG:
1544 case ISD::AssertSext:
1545 case ISD::AssertZext:
1546 if (Val.getOperand(0).getValueType().isInteger()) {
1547 VTSDNode *T = cast<VTSDNode>(Val.getOperand(1));
1548 if (T->getVT().getSizeInBits() == FromBits) {
1549 Src = Val.getOperand(0);
1555 // Check if this is an AND with "FromBits" of lower bits set to 1.
1556 uint64_t FromMask = (1 << FromBits) - 1;
1557 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
1558 if (C->getZExtValue() == FromMask) {
1559 Src = Val.getOperand(1);
1563 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
1564 if (C->getZExtValue() == FromMask) {
1565 Src = Val.getOperand(0);
1573 // OR/XOR with the lower "FromBits" bits set to 0.
1574 uint64_t FromMask = (1 << FromBits) - 1;
1575 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
1576 if ((C->getZExtValue() & FromMask) == 0) {
1577 Src = Val.getOperand(1);
1581 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
1582 if ((C->getZExtValue() & FromMask) == 0) {
1583 Src = Val.getOperand(0);