1//===-- HexagonISelDAGToDAG.cpp - A dag to dag inst selector for Hexagon --===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines an instruction selector for the Hexagon target.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "hexagon-isel"
15#include "Hexagon.h"
16#include "HexagonISelLowering.h"
17#include "HexagonTargetMachine.h"
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/IR/Intrinsics.h"
20#include "llvm/CodeGen/SelectionDAGISel.h"
21#include "llvm/Support/CommandLine.h"
22#include "llvm/Support/Compiler.h"
23#include "llvm/Support/Debug.h"
24using namespace llvm;
25
26static
27cl::opt<unsigned>
28MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders",
29  cl::Hidden, cl::init(2),
30  cl::desc("Maximum number of uses of a global address such that we still us a"
31           "constant extended instruction"));
32
33//===----------------------------------------------------------------------===//
34// Instruction Selector Implementation
35//===----------------------------------------------------------------------===//
36
37namespace llvm {
38  void initializeHexagonDAGToDAGISelPass(PassRegistry&);
39}
40
41//===--------------------------------------------------------------------===//
42/// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
43/// instructions for SelectionDAG operations.
44///
45namespace {
46class HexagonDAGToDAGISel : public SelectionDAGISel {
47  /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
48  /// make the right decision when generating code for different targets.
49  const HexagonSubtarget &Subtarget;
50
51  // Keep a reference to HexagonTargetMachine.
52  const HexagonTargetMachine& TM;
53  const HexagonInstrInfo *TII;
54  DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap;
55public:
56  explicit HexagonDAGToDAGISel(const HexagonTargetMachine &targetmachine,
57                               CodeGenOpt::Level OptLevel)
58    : SelectionDAGISel(targetmachine, OptLevel),
59      Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
60      TM(targetmachine),
61      TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {
62    initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
63  }
64  bool hasNumUsesBelowThresGA(SDNode *N) const;
65
66  SDNode *Select(SDNode *N);
67
68  // Complex Pattern Selectors.
69  inline bool foldGlobalAddress(SDValue &N, SDValue &R);
70  inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
71  bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
72  bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
73  bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
74  bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
75  bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
76  bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
77  bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
78  bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
79  bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
80  bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
81  bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
82
83  virtual const char *getPassName() const {
84    return "Hexagon DAG->DAG Pattern Instruction Selection";
85  }
86
87  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
88  /// inline asm expressions.
89  virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
90                                            char ConstraintCode,
91                                            std::vector<SDValue> &OutOps);
92  bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
93
94  SDNode *SelectLoad(SDNode *N);
95  SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl);
96  SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl);
97  SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
98                                        DebugLoc dl);
99  SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
100                                        DebugLoc dl);
101  SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl);
102  SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl);
103  SDNode *SelectStore(SDNode *N);
104  SDNode *SelectSHL(SDNode *N);
105  SDNode *SelectSelect(SDNode *N);
106  SDNode *SelectTruncate(SDNode *N);
107  SDNode *SelectMul(SDNode *N);
108  SDNode *SelectZeroExtend(SDNode *N);
109  SDNode *SelectIntrinsicWOChain(SDNode *N);
110  SDNode *SelectIntrinsicWChain(SDNode *N);
111  SDNode *SelectConstant(SDNode *N);
112  SDNode *SelectConstantFP(SDNode *N);
113  SDNode *SelectAdd(SDNode *N);
114  bool isConstExtProfitable(SDNode *N) const;
115
116// XformMskToBitPosU5Imm - Returns the bit position which
117// the single bit 32 bit mask represents.
118// Used in Clr and Set bit immediate memops.
119SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
120  int32_t bitPos;
121  bitPos = Log2_32(Imm);
122  assert(bitPos >= 0 && bitPos < 32 &&
123         "Constant out of range for 32 BitPos Memops");
124  return CurDAG->getTargetConstant(bitPos, MVT::i32);
125}
126
127// XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
128// mask represents. Used in Clr and Set bit immediate memops.
129SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
130  return XformMskToBitPosU5Imm(Imm);
131}
132
133// XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
134// mask represents. Used in Clr and Set bit immediate memops.
135SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
136  return XformMskToBitPosU5Imm(Imm);
137}
138
139// Return true if there is exactly one bit set in V, i.e., if V is one of the
140// following integers: 2^0, 2^1, ..., 2^31.
141bool ImmIsSingleBit(uint32_t v) const {
142  uint32_t c = CountPopulation_64(v);
143  // Only return true if we counted 1 bit.
144  return c == 1;
145}
146
147// XformM5ToU5Imm - Return a target constant with the specified value, of type
148// i32 where the negative literal is transformed into a positive literal for
149// use in -= memops.
150inline SDValue XformM5ToU5Imm(signed Imm) {
151   assert( (Imm >= -31 && Imm <= -1)  && "Constant out of range for Memops");
152   return CurDAG->getTargetConstant( - Imm, MVT::i32);
153}
154
155
156// XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
157// [1..128], used in cmpb.gtu instructions.
158inline SDValue XformU7ToU7M1Imm(signed Imm) {
159  assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
160  return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
161}
162
163// XformS8ToS8M1Imm - Return a target constant decremented by 1.
164inline SDValue XformSToSM1Imm(signed Imm) {
165  return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
166}
167
168// XformU8ToU8M1Imm - Return a target constant decremented by 1.
169inline SDValue XformUToUM1Imm(unsigned Imm) {
170  assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
171  return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
172}
173
174// Include the pieces autogenerated from the target description.
175#include "HexagonGenDAGISel.inc"
176};
177}  // end anonymous namespace
178
179
180/// createHexagonISelDag - This pass converts a legalized DAG into a
181/// Hexagon-specific DAG, ready for instruction scheduling.
182///
183FunctionPass *llvm::createHexagonISelDag(const HexagonTargetMachine &TM,
184                                         CodeGenOpt::Level OptLevel) {
185  return new HexagonDAGToDAGISel(TM, OptLevel);
186}
187
188static void initializePassOnce(PassRegistry &Registry) {
189  const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
190  PassInfo *PI = new PassInfo(Name, "hexagon-isel",
191                              &SelectionDAGISel::ID, 0, false, false);
192  Registry.registerPass(*PI, true);
193}
194
195void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
196  CALL_ONCE_INITIALIZATION(initializePassOnce)
197}
198
199
200static bool IsS11_0_Offset(SDNode * S) {
201    ConstantSDNode *N = cast<ConstantSDNode>(S);
202
203  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
204  // field.
205  int64_t v = (int64_t)N->getSExtValue();
206  return isInt<11>(v);
207}
208
209
210static bool IsS11_1_Offset(SDNode * S) {
211    ConstantSDNode *N = cast<ConstantSDNode>(S);
212
213  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
214  // field.
215  int64_t v = (int64_t)N->getSExtValue();
216  return isShiftedInt<11,1>(v);
217}
218
219
220static bool IsS11_2_Offset(SDNode * S) {
221    ConstantSDNode *N = cast<ConstantSDNode>(S);
222
223  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
224  // field.
225  int64_t v = (int64_t)N->getSExtValue();
226  return isShiftedInt<11,2>(v);
227}
228
229
230static bool IsS11_3_Offset(SDNode * S) {
231    ConstantSDNode *N = cast<ConstantSDNode>(S);
232
233  // immS16 predicate - True if the immediate fits in a 16-bit sign extended
234  // field.
235  int64_t v = (int64_t)N->getSExtValue();
236  return isShiftedInt<11,3>(v);
237}
238
239
240static bool IsU6_0_Offset(SDNode * S) {
241    ConstantSDNode *N = cast<ConstantSDNode>(S);
242
243  // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
244  // field.
245  int64_t v = (int64_t)N->getSExtValue();
246  return isUInt<6>(v);
247}
248
249
250static bool IsU6_1_Offset(SDNode * S) {
251    ConstantSDNode *N = cast<ConstantSDNode>(S);
252
253  // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
254  // field.
255  int64_t v = (int64_t)N->getSExtValue();
256  return isShiftedUInt<6,1>(v);
257}
258
259
260static bool IsU6_2_Offset(SDNode * S) {
261    ConstantSDNode *N = cast<ConstantSDNode>(S);
262
263  // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
264  // field.
265  int64_t v = (int64_t)N->getSExtValue();
266  return isShiftedUInt<6,2>(v);
267}
268
269
270// Intrinsics that return a a predicate.
271static unsigned doesIntrinsicReturnPredicate(unsigned ID)
272{
273  switch (ID) {
274    default:
275      return 0;
276    case Intrinsic::hexagon_C2_cmpeq:
277    case Intrinsic::hexagon_C2_cmpgt:
278    case Intrinsic::hexagon_C2_cmpgtu:
279    case Intrinsic::hexagon_C2_cmpgtup:
280    case Intrinsic::hexagon_C2_cmpgtp:
281    case Intrinsic::hexagon_C2_cmpeqp:
282    case Intrinsic::hexagon_C2_bitsset:
283    case Intrinsic::hexagon_C2_bitsclr:
284    case Intrinsic::hexagon_C2_cmpeqi:
285    case Intrinsic::hexagon_C2_cmpgti:
286    case Intrinsic::hexagon_C2_cmpgtui:
287    case Intrinsic::hexagon_C2_cmpgei:
288    case Intrinsic::hexagon_C2_cmpgeui:
289    case Intrinsic::hexagon_C2_cmplt:
290    case Intrinsic::hexagon_C2_cmpltu:
291    case Intrinsic::hexagon_C2_bitsclri:
292    case Intrinsic::hexagon_C2_and:
293    case Intrinsic::hexagon_C2_or:
294    case Intrinsic::hexagon_C2_xor:
295    case Intrinsic::hexagon_C2_andn:
296    case Intrinsic::hexagon_C2_not:
297    case Intrinsic::hexagon_C2_orn:
298    case Intrinsic::hexagon_C2_pxfer_map:
299    case Intrinsic::hexagon_C2_any8:
300    case Intrinsic::hexagon_C2_all8:
301    case Intrinsic::hexagon_A2_vcmpbeq:
302    case Intrinsic::hexagon_A2_vcmpbgtu:
303    case Intrinsic::hexagon_A2_vcmpheq:
304    case Intrinsic::hexagon_A2_vcmphgt:
305    case Intrinsic::hexagon_A2_vcmphgtu:
306    case Intrinsic::hexagon_A2_vcmpweq:
307    case Intrinsic::hexagon_A2_vcmpwgt:
308    case Intrinsic::hexagon_A2_vcmpwgtu:
309    case Intrinsic::hexagon_C2_tfrrp:
310    case Intrinsic::hexagon_S2_tstbit_i:
311    case Intrinsic::hexagon_S2_tstbit_r:
312      return 1;
313  }
314}
315
316
317// Intrinsics that have predicate operands.
318static unsigned doesIntrinsicContainPredicate(unsigned ID)
319{
320  switch (ID) {
321    default:
322      return 0;
323    case Intrinsic::hexagon_C2_tfrpr:
324      return Hexagon::TFR_RsPd;
325    case Intrinsic::hexagon_C2_and:
326      return Hexagon::AND_pp;
327    case Intrinsic::hexagon_C2_xor:
328      return Hexagon::XOR_pp;
329    case Intrinsic::hexagon_C2_or:
330      return Hexagon::OR_pp;
331    case Intrinsic::hexagon_C2_not:
332      return Hexagon::NOT_p;
333    case Intrinsic::hexagon_C2_any8:
334      return Hexagon::ANY_pp;
335    case Intrinsic::hexagon_C2_all8:
336      return Hexagon::ALL_pp;
337    case Intrinsic::hexagon_C2_vitpack:
338      return Hexagon::VITPACK_pp;
339    case Intrinsic::hexagon_C2_mask:
340      return Hexagon::MASK_p;
341    case Intrinsic::hexagon_C2_mux:
342      return Hexagon::MUX_rr;
343
344      // Mapping hexagon_C2_muxir to MUX_pri.  This is pretty weird - but
345      // that's how it's mapped in q6protos.h.
346    case Intrinsic::hexagon_C2_muxir:
347      return Hexagon::MUX_ri;
348
349      // Mapping hexagon_C2_muxri to MUX_pir.  This is pretty weird - but
350      // that's how it's mapped in q6protos.h.
351    case Intrinsic::hexagon_C2_muxri:
352      return Hexagon::MUX_ir;
353
354    case Intrinsic::hexagon_C2_muxii:
355      return Hexagon::MUX_ii;
356    case Intrinsic::hexagon_C2_vmux:
357      return Hexagon::VMUX_prr64;
358    case Intrinsic::hexagon_S2_valignrb:
359      return Hexagon::VALIGN_rrp;
360    case Intrinsic::hexagon_S2_vsplicerb:
361      return Hexagon::VSPLICE_rrp;
362  }
363}
364
365
366static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
367  if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
368    return true;
369  }
370  if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
371    return true;
372  }
373  if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
374    return true;
375  }
376  if (MemType == MVT::i8 && isInt<11>(Offset)) {
377    return true;
378  }
379  return false;
380}
381
382
383//
384// Try to lower loads of GlobalAdresses into base+offset loads.  Custom
385// lowering for GlobalAddress nodes has already turned it into a
386// CONST32.
387//
388SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
389  SDValue Chain = LD->getChain();
390  SDNode* Const32 = LD->getBasePtr().getNode();
391  unsigned Opcode = 0;
392
393  if (Const32->getOpcode() == HexagonISD::CONST32 &&
394      ISD::isNormalLoad(LD)) {
395    SDValue Base = Const32->getOperand(0);
396    EVT LoadedVT = LD->getMemoryVT();
397    int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
398    if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
399      MVT PointerTy = TLI.getPointerTy();
400      const GlobalValue* GV =
401        cast<GlobalAddressSDNode>(Base)->getGlobal();
402      SDValue TargAddr =
403        CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
404      SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
405                                               dl, PointerTy,
406                                               TargAddr);
407      // Figure out base + offset opcode
408      if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
409      else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
410      else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
411      else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
412      else llvm_unreachable("unknown memory type");
413
414      // Build indexed load.
415      SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
416      SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
417                                              LD->getValueType(0),
418                                              MVT::Other,
419                                              SDValue(NewBase,0),
420                                              TargetConstOff,
421                                              Chain);
422      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
423      MemOp[0] = LD->getMemOperand();
424      cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
425      ReplaceUses(LD, Result);
426      return Result;
427    }
428  }
429
430  return SelectCode(LD);
431}
432
433
434SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
435                                                           unsigned Opcode,
436                                                           DebugLoc dl)
437{
438  SDValue Chain = LD->getChain();
439  EVT LoadedVT = LD->getMemoryVT();
440  SDValue Base = LD->getBasePtr();
441  SDValue Offset = LD->getOffset();
442  SDNode *OffsetNode = Offset.getNode();
443  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
444  SDValue N1 = LD->getOperand(1);
445  SDValue CPTmpN1_0;
446  SDValue CPTmpN1_1;
447  if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
448      N1.getNode()->getValueType(0) == MVT::i32) {
449    if (TII->isValidAutoIncImm(LoadedVT, Val)) {
450      SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
451      SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
452                                                MVT::Other, Base, TargetConst,
453                                                Chain);
454      SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
455                                                SDValue(Result_1, 0));
456      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
457      MemOp[0] = LD->getMemOperand();
458      cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
459      const SDValue Froms[] = { SDValue(LD, 0),
460                                SDValue(LD, 1),
461                                SDValue(LD, 2)
462      };
463      const SDValue Tos[]   = { SDValue(Result_2, 0),
464                                SDValue(Result_1, 1),
465                                SDValue(Result_1, 2)
466      };
467      ReplaceUses(Froms, Tos, 3);
468      return Result_2;
469    }
470    SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
471    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
472    SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
473                                              MVT::Other, Base, TargetConst0,
474                                              Chain);
475    SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
476                                                MVT::i64, SDValue(Result_1, 0));
477    SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
478                                              MVT::i32, Base, TargetConstVal,
479                                                SDValue(Result_1, 1));
480    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
481    MemOp[0] = LD->getMemOperand();
482    cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
483    const SDValue Froms[] = { SDValue(LD, 0),
484                              SDValue(LD, 1),
485                              SDValue(LD, 2)
486    };
487    const SDValue Tos[]   = { SDValue(Result_2, 0),
488                              SDValue(Result_3, 0),
489                              SDValue(Result_1, 1)
490    };
491    ReplaceUses(Froms, Tos, 3);
492    return Result_2;
493  }
494  return SelectCode(LD);
495}
496
497
498SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
499                                                           unsigned Opcode,
500                                                           DebugLoc dl)
501{
502  SDValue Chain = LD->getChain();
503  EVT LoadedVT = LD->getMemoryVT();
504  SDValue Base = LD->getBasePtr();
505  SDValue Offset = LD->getOffset();
506  SDNode *OffsetNode = Offset.getNode();
507  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
508  SDValue N1 = LD->getOperand(1);
509  SDValue CPTmpN1_0;
510  SDValue CPTmpN1_1;
511  if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
512      N1.getNode()->getValueType(0) == MVT::i32) {
513    if (TII->isValidAutoIncImm(LoadedVT, Val)) {
514      SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
515      SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
516      SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
517                                                MVT::i32, MVT::Other, Base,
518                                                TargetConstVal, Chain);
519      SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
520                                                TargetConst0);
521      SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
522                                                MVT::i64, MVT::Other,
523                                                SDValue(Result_2,0),
524                                                SDValue(Result_1,0));
525      MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
526      MemOp[0] = LD->getMemOperand();
527      cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
528      const SDValue Froms[] = { SDValue(LD, 0),
529                                SDValue(LD, 1),
530                                SDValue(LD, 2)
531      };
532      const SDValue Tos[]   = { SDValue(Result_3, 0),
533                                SDValue(Result_1, 1),
534                                SDValue(Result_1, 2)
535      };
536      ReplaceUses(Froms, Tos, 3);
537      return Result_3;
538    }
539
540    // Generate an indirect load.
541    SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
542    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
543    SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
544                                              MVT::Other,
545                                              Base, TargetConst0, Chain);
546    SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
547                                              TargetConst0);
548    SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
549                                              MVT::i64, MVT::Other,
550                                              SDValue(Result_2,0),
551                                              SDValue(Result_1,0));
552    // Add offset to base.
553    SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
554                                              Base, TargetConstVal,
555                                              SDValue(Result_1, 1));
556    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
557    MemOp[0] = LD->getMemOperand();
558    cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
559    const SDValue Froms[] = { SDValue(LD, 0),
560                              SDValue(LD, 1),
561                              SDValue(LD, 2)
562    };
563    const SDValue Tos[]   = { SDValue(Result_3, 0), // Load value.
564                              SDValue(Result_4, 0), // New address.
565                              SDValue(Result_1, 1)
566    };
567    ReplaceUses(Froms, Tos, 3);
568    return Result_3;
569  }
570
571  return SelectCode(LD);
572}
573
574
575SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
576  SDValue Chain = LD->getChain();
577  SDValue Base = LD->getBasePtr();
578  SDValue Offset = LD->getOffset();
579  SDNode *OffsetNode = Offset.getNode();
580  // Get the constant value.
581  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
582  EVT LoadedVT = LD->getMemoryVT();
583  unsigned Opcode = 0;
584
585  // Check for zero ext loads.
586  bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
587
588  // Figure out the opcode.
589  if (LoadedVT == MVT::i64) {
590    if (TII->isValidAutoIncImm(LoadedVT, Val))
591      Opcode = Hexagon::POST_LDrid;
592    else
593      Opcode = Hexagon::LDrid;
594  } else if (LoadedVT == MVT::i32) {
595    if (TII->isValidAutoIncImm(LoadedVT, Val))
596      Opcode = Hexagon::POST_LDriw;
597    else
598      Opcode = Hexagon::LDriw;
599  } else if (LoadedVT == MVT::i16) {
600    if (TII->isValidAutoIncImm(LoadedVT, Val))
601      Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
602    else
603      Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
604  } else if (LoadedVT == MVT::i8) {
605    if (TII->isValidAutoIncImm(LoadedVT, Val))
606      Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
607    else
608      Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
609  } else
610    llvm_unreachable("unknown memory type");
611
612  // For zero ext i64 loads, we need to add combine instructions.
613  if (LD->getValueType(0) == MVT::i64 &&
614      LD->getExtensionType() == ISD::ZEXTLOAD) {
615    return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
616  }
617  if (LD->getValueType(0) == MVT::i64 &&
618             LD->getExtensionType() == ISD::SEXTLOAD) {
619    // Handle sign ext i64 loads.
620    return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
621  }
622  if (TII->isValidAutoIncImm(LoadedVT, Val)) {
623    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
624    SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
625                                            LD->getValueType(0),
626                                            MVT::i32, MVT::Other, Base,
627                                            TargetConstVal, Chain);
628    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
629    MemOp[0] = LD->getMemOperand();
630    cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
631    const SDValue Froms[] = { SDValue(LD, 0),
632                              SDValue(LD, 1),
633                              SDValue(LD, 2)
634    };
635    const SDValue Tos[]   = { SDValue(Result, 0),
636                              SDValue(Result, 1),
637                              SDValue(Result, 2)
638    };
639    ReplaceUses(Froms, Tos, 3);
640    return Result;
641  } else {
642    SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
643    SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
644    SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
645                                              LD->getValueType(0),
646                                              MVT::Other, Base, TargetConst0,
647                                              Chain);
648    SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
649                                              Base, TargetConstVal,
650                                              SDValue(Result_1, 1));
651    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
652    MemOp[0] = LD->getMemOperand();
653    cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
654    const SDValue Froms[] = { SDValue(LD, 0),
655                              SDValue(LD, 1),
656                              SDValue(LD, 2)
657    };
658    const SDValue Tos[]   = { SDValue(Result_1, 0),
659                              SDValue(Result_2, 0),
660                              SDValue(Result_1, 1)
661    };
662    ReplaceUses(Froms, Tos, 3);
663    return Result_1;
664  }
665}
666
667
668SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
669  SDNode *result;
670  DebugLoc dl = N->getDebugLoc();
671  LoadSDNode *LD = cast<LoadSDNode>(N);
672  ISD::MemIndexedMode AM = LD->getAddressingMode();
673
674  // Handle indexed loads.
675  if (AM != ISD::UNINDEXED) {
676    result = SelectIndexedLoad(LD, dl);
677  } else {
678    result = SelectBaseOffsetLoad(LD, dl);
679  }
680
681  return result;
682}
683
684
685SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
686  SDValue Chain = ST->getChain();
687  SDValue Base = ST->getBasePtr();
688  SDValue Offset = ST->getOffset();
689  SDValue Value = ST->getValue();
690  SDNode *OffsetNode = Offset.getNode();
691  // Get the constant value.
692  int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
693  EVT StoredVT = ST->getMemoryVT();
694
695  // Offset value must be within representable range
696  // and must have correct alignment properties.
697  if (TII->isValidAutoIncImm(StoredVT, Val)) {
698    SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
699                     Chain};
700    unsigned Opcode = 0;
701
702    // Figure out the post inc version of opcode.
703    if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
704    else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
705    else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
706    else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
707    else llvm_unreachable("unknown memory type");
708
709    // Build post increment store.
710    SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
711                                            MVT::Other, Ops);
712    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
713    MemOp[0] = ST->getMemOperand();
714    cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
715
716    ReplaceUses(ST, Result);
717    ReplaceUses(SDValue(ST,1), SDValue(Result,1));
718    return Result;
719  }
720
721  // Note: Order of operands matches the def of instruction:
722  // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
723  // and it differs for POST_ST* for instance.
724  SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
725                    Chain};
726  unsigned Opcode = 0;
727
728  // Figure out the opcode.
729  if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
730  else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
731  else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
732  else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
733  else llvm_unreachable("unknown memory type");
734
735  // Build regular store.
736  SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
737  SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
738  // Build splitted incriment instruction.
739  SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
740                                            Base,
741                                            TargetConstVal,
742                                            SDValue(Result_1, 0));
743  MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
744  MemOp[0] = ST->getMemOperand();
745  cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
746
747  ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
748  ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
749  return Result_2;
750}
751
752
753SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
754                                                   DebugLoc dl) {
755  SDValue Chain = ST->getChain();
756  SDNode* Const32 = ST->getBasePtr().getNode();
757  SDValue Value = ST->getValue();
758  unsigned Opcode = 0;
759
760  // Try to lower stores of GlobalAdresses into indexed stores.  Custom
761  // lowering for GlobalAddress nodes has already turned it into a
762  // CONST32.  Avoid truncating stores for the moment.  Post-inc stores
763  // do the same.  Don't think there's a reason for it, so will file a
764  // bug to fix.
765  if ((Const32->getOpcode() == HexagonISD::CONST32) &&
766      !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
767    SDValue Base = Const32->getOperand(0);
768    if (Base.getOpcode() == ISD::TargetGlobalAddress) {
769      EVT StoredVT = ST->getMemoryVT();
770      int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
771      if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
772        MVT PointerTy = TLI.getPointerTy();
773        const GlobalValue* GV =
774          cast<GlobalAddressSDNode>(Base)->getGlobal();
775        SDValue TargAddr =
776          CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
777        SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
778                                                 dl, PointerTy,
779                                                 TargAddr);
780
781        // Figure out base + offset opcode
782        if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
783        else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
784        else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
785        else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
786        else llvm_unreachable("unknown memory type");
787
788        SDValue Ops[] = {SDValue(NewBase,0),
789                         CurDAG->getTargetConstant(Offset,PointerTy),
790                         Value, Chain};
791        // build indexed store
792        SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
793                                                MVT::Other, Ops);
794        MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
795        MemOp[0] = ST->getMemOperand();
796        cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
797        ReplaceUses(ST, Result);
798        return Result;
799      }
800    }
801  }
802
803  return SelectCode(ST);
804}
805
806
807SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
808  DebugLoc dl = N->getDebugLoc();
809  StoreSDNode *ST = cast<StoreSDNode>(N);
810  ISD::MemIndexedMode AM = ST->getAddressingMode();
811
812  // Handle indexed stores.
813  if (AM != ISD::UNINDEXED) {
814    return SelectIndexedStore(ST, dl);
815  }
816
817  return SelectBaseOffsetStore(ST, dl);
818}
819
820SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
821  DebugLoc dl = N->getDebugLoc();
822
823  //
824  // %conv.i = sext i32 %tmp1 to i64
825  // %conv2.i = sext i32 %add to i64
826  // %mul.i = mul nsw i64 %conv2.i, %conv.i
827  //
828  //   --- match with the following ---
829  //
830  // %mul.i = mpy (%tmp1, %add)
831  //
832
833  if (N->getValueType(0) == MVT::i64) {
834    // Shifting a i64 signed multiply.
835    SDValue MulOp0 = N->getOperand(0);
836    SDValue MulOp1 = N->getOperand(1);
837
838    SDValue OP0;
839    SDValue OP1;
840
841    // Handle sign_extend and sextload.
842    if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
843      SDValue Sext0 = MulOp0.getOperand(0);
844      if (Sext0.getNode()->getValueType(0) != MVT::i32) {
845        return SelectCode(N);
846      }
847
848      OP0 = Sext0;
849    } else if (MulOp0.getOpcode() == ISD::LOAD) {
850      LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
851      if (LD->getMemoryVT() != MVT::i32 ||
852          LD->getExtensionType() != ISD::SEXTLOAD ||
853          LD->getAddressingMode() != ISD::UNINDEXED) {
854        return SelectCode(N);
855      }
856
857      SDValue Chain = LD->getChain();
858      SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
859      OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
860                                            MVT::Other,
861                                            LD->getBasePtr(), TargetConst0,
862                                            Chain), 0);
863    } else {
864      return SelectCode(N);
865    }
866
867    // Same goes for the second operand.
868    if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
869      SDValue Sext1 = MulOp1.getOperand(0);
870      if (Sext1.getNode()->getValueType(0) != MVT::i32) {
871        return SelectCode(N);
872      }
873
874      OP1 = Sext1;
875    } else if (MulOp1.getOpcode() == ISD::LOAD) {
876      LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
877      if (LD->getMemoryVT() != MVT::i32 ||
878          LD->getExtensionType() != ISD::SEXTLOAD ||
879          LD->getAddressingMode() != ISD::UNINDEXED) {
880        return SelectCode(N);
881      }
882
883      SDValue Chain = LD->getChain();
884      SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
885      OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
886                                            MVT::Other,
887                                            LD->getBasePtr(), TargetConst0,
888                                            Chain), 0);
889    } else {
890      return SelectCode(N);
891    }
892
893    // Generate a mpy instruction.
894    SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
895                                            OP0, OP1);
896    ReplaceUses(N, Result);
897    return Result;
898  }
899
900  return SelectCode(N);
901}
902
903
904SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
905  DebugLoc dl = N->getDebugLoc();
906  SDValue N0 = N->getOperand(0);
907  if (N0.getOpcode() == ISD::SETCC) {
908    SDValue N00 = N0.getOperand(0);
909    if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
910      SDValue N000 = N00.getOperand(0);
911      SDValue N001 = N00.getOperand(1);
912      if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
913        SDValue N01 = N0.getOperand(1);
914        SDValue N02 = N0.getOperand(2);
915
916        // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
917        // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
918        // IntRegs:i32:$src2)
919        // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
920        // Pattern complexity = 9  cost = 1  size = 0.
921        if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
922          SDValue N1 = N->getOperand(1);
923          if (N01 == N1) {
924            SDValue N2 = N->getOperand(2);
925            if (N000 == N2 &&
926                N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
927                N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
928              SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
929                                                        MVT::i32, N000);
930              SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
931                                                      MVT::i32,
932                                                      SDValue(SextNode, 0),
933                                                      N1);
934              ReplaceUses(N, Result);
935              return Result;
936            }
937          }
938        }
939
940        // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
941        // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
942        // IntRegs:i32:$src2)
943        // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
944        // Pattern complexity = 9  cost = 1  size = 0.
945        if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
946          SDValue N1 = N->getOperand(1);
947          if (N01 == N1) {
948            SDValue N2 = N->getOperand(2);
949            if (N000 == N2 &&
950                N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
951                N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
952              SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
953                                                        MVT::i32, N000);
954              SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
955                                                      MVT::i32,
956                                                      SDValue(SextNode, 0),
957                                                      N1);
958              ReplaceUses(N, Result);
959              return Result;
960            }
961          }
962        }
963      }
964    }
965  }
966
967  return SelectCode(N);
968}
969
970
971SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
972  DebugLoc dl = N->getDebugLoc();
973  SDValue Shift = N->getOperand(0);
974
975  //
976  // %conv.i = sext i32 %tmp1 to i64
977  // %conv2.i = sext i32 %add to i64
978  // %mul.i = mul nsw i64 %conv2.i, %conv.i
979  // %shr5.i = lshr i64 %mul.i, 32
980  // %conv3.i = trunc i64 %shr5.i to i32
981  //
982  //   --- match with the following ---
983  //
984  // %conv3.i = mpy (%tmp1, %add)
985  //
986  // Trunc to i32.
987  if (N->getValueType(0) == MVT::i32) {
988    // Trunc from i64.
989    if (Shift.getNode()->getValueType(0) == MVT::i64) {
990      // Trunc child is logical shift right.
991      if (Shift.getOpcode() != ISD::SRL) {
992        return SelectCode(N);
993      }
994
995      SDValue ShiftOp0 = Shift.getOperand(0);
996      SDValue ShiftOp1 = Shift.getOperand(1);
997
998      // Shift by const 32
999      if (ShiftOp1.getOpcode() != ISD::Constant) {
1000        return SelectCode(N);
1001      }
1002
1003      int32_t ShiftConst =
1004        cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
1005      if (ShiftConst != 32) {
1006        return SelectCode(N);
1007      }
1008
1009      // Shifting a i64 signed multiply
1010      SDValue Mul = ShiftOp0;
1011      if (Mul.getOpcode() != ISD::MUL) {
1012        return SelectCode(N);
1013      }
1014
1015      SDValue MulOp0 = Mul.getOperand(0);
1016      SDValue MulOp1 = Mul.getOperand(1);
1017
1018      SDValue OP0;
1019      SDValue OP1;
1020
1021      // Handle sign_extend and sextload
1022      if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
1023        SDValue Sext0 = MulOp0.getOperand(0);
1024        if (Sext0.getNode()->getValueType(0) != MVT::i32) {
1025          return SelectCode(N);
1026        }
1027
1028        OP0 = Sext0;
1029      } else if (MulOp0.getOpcode() == ISD::LOAD) {
1030        LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
1031        if (LD->getMemoryVT() != MVT::i32 ||
1032            LD->getExtensionType() != ISD::SEXTLOAD ||
1033            LD->getAddressingMode() != ISD::UNINDEXED) {
1034          return SelectCode(N);
1035        }
1036
1037        SDValue Chain = LD->getChain();
1038        SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1039        OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1040                                              MVT::Other,
1041                                              LD->getBasePtr(),
1042                                              TargetConst0, Chain), 0);
1043      } else {
1044        return SelectCode(N);
1045      }
1046
1047      // Same goes for the second operand.
1048      if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
1049        SDValue Sext1 = MulOp1.getOperand(0);
1050        if (Sext1.getNode()->getValueType(0) != MVT::i32)
1051          return SelectCode(N);
1052
1053        OP1 = Sext1;
1054      } else if (MulOp1.getOpcode() == ISD::LOAD) {
1055        LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
1056        if (LD->getMemoryVT() != MVT::i32 ||
1057            LD->getExtensionType() != ISD::SEXTLOAD ||
1058            LD->getAddressingMode() != ISD::UNINDEXED) {
1059          return SelectCode(N);
1060        }
1061
1062        SDValue Chain = LD->getChain();
1063        SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1064        OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1065                                              MVT::Other,
1066                                              LD->getBasePtr(),
1067                                              TargetConst0, Chain), 0);
1068      } else {
1069        return SelectCode(N);
1070      }
1071
1072      // Generate a mpy instruction.
1073      SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
1074                                              OP0, OP1);
1075      ReplaceUses(N, Result);
1076      return Result;
1077    }
1078  }
1079
1080  return SelectCode(N);
1081}
1082
1083
1084SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
1085  DebugLoc dl = N->getDebugLoc();
1086  if (N->getValueType(0) == MVT::i32) {
1087    SDValue Shl_0 = N->getOperand(0);
1088    SDValue Shl_1 = N->getOperand(1);
1089    // RHS is const.
1090    if (Shl_1.getOpcode() == ISD::Constant) {
1091      if (Shl_0.getOpcode() == ISD::MUL) {
1092        SDValue Mul_0 = Shl_0.getOperand(0); // Val
1093        SDValue Mul_1 = Shl_0.getOperand(1); // Const
1094        // RHS of mul is const.
1095        if (Mul_1.getOpcode() == ISD::Constant) {
1096          int32_t ShlConst =
1097            cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1098          int32_t MulConst =
1099            cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1100          int32_t ValConst = MulConst << ShlConst;
1101          SDValue Val = CurDAG->getTargetConstant(ValConst,
1102                                                  MVT::i32);
1103          if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1104            if (isInt<9>(CN->getSExtValue())) {
1105              SDNode* Result =
1106                CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
1107                                       MVT::i32, Mul_0, Val);
1108              ReplaceUses(N, Result);
1109              return Result;
1110            }
1111
1112        }
1113      } else if (Shl_0.getOpcode() == ISD::SUB) {
1114        SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1115        SDValue Sub_1 = Shl_0.getOperand(1); // Val
1116        if (Sub_0.getOpcode() == ISD::Constant) {
1117          int32_t SubConst =
1118            cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1119          if (SubConst == 0) {
1120            if (Sub_1.getOpcode() == ISD::SHL) {
1121              SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1122              SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1123              if (Shl2_1.getOpcode() == ISD::Constant) {
1124                int32_t ShlConst =
1125                  cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1126                int32_t Shl2Const =
1127                  cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1128                int32_t ValConst = 1 << (ShlConst+Shl2Const);
1129                SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1130                if (ConstantSDNode *CN =
1131                    dyn_cast<ConstantSDNode>(Val.getNode()))
1132                  if (isInt<9>(CN->getSExtValue())) {
1133                    SDNode* Result =
1134                      CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
1135                                             Shl2_0, Val);
1136                    ReplaceUses(N, Result);
1137                    return Result;
1138                  }
1139              }
1140            }
1141          }
1142        }
1143      }
1144    }
1145  }
1146  return SelectCode(N);
1147}
1148
1149
1150//
1151// If there is an zero_extend followed an intrinsic in DAG (this means - the
1152// result of the intrinsic is predicate); convert the zero_extend to
1153// transfer instruction.
1154//
1155// Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1156// converted into a MUX as predicate registers defined as 1 bit in the
1157// compiler. Architecture defines them as 8-bit registers.
1158// We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1159//
1160SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1161  DebugLoc dl = N->getDebugLoc();
1162  SDNode *IsIntrinsic = N->getOperand(0).getNode();
1163  if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1164    unsigned ID =
1165      cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1166    if (doesIntrinsicReturnPredicate(ID)) {
1167      // Now we need to differentiate target data types.
1168      if (N->getValueType(0) == MVT::i64) {
1169        // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1170        SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1171        SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1172                                                  MVT::i32,
1173                                                  SDValue(IsIntrinsic, 0));
1174        SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
1175                                                  MVT::i32,
1176                                                  TargetConst0);
1177        SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
1178                                                  MVT::i64, MVT::Other,
1179                                                  SDValue(Result_2, 0),
1180                                                  SDValue(Result_1, 0));
1181        ReplaceUses(N, Result_3);
1182        return Result_3;
1183      }
1184      if (N->getValueType(0) == MVT::i32) {
1185        // Convert the zero_extend to Rs = Pd
1186        SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1187                                              MVT::i32,
1188                                              SDValue(IsIntrinsic, 0));
1189        ReplaceUses(N, RsPd);
1190        return RsPd;
1191      }
1192      llvm_unreachable("Unexpected value type");
1193    }
1194  }
1195  return SelectCode(N);
1196}
1197
1198
1199//
1200// Checking for intrinsics which have predicate registers as operand(s)
1201// and lowering to the actual intrinsic.
1202//
1203SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1204  DebugLoc dl = N->getDebugLoc();
1205  unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1206  unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
1207
1208  // We are concerned with only those intrinsics that have predicate registers
1209  // as at least one of the operands.
1210  if (IntrinsicWithPred) {
1211    SmallVector<SDValue, 8> Ops;
1212    const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
1213    const TargetRegisterInfo *TRI = TM.getRegisterInfo();
1214
1215    // Iterate over all the operands of the intrinsics.
1216    // For PredRegs, do the transfer.
1217    // For Double/Int Regs, just preserve the value
1218    // For immediates, lower it.
1219    for (unsigned i = 1; i < N->getNumOperands(); ++i) {
1220      SDNode *Arg = N->getOperand(i).getNode();
1221      const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF);
1222
1223      if (RC == &Hexagon::IntRegsRegClass ||
1224          RC == &Hexagon::DoubleRegsRegClass) {
1225        Ops.push_back(SDValue(Arg, 0));
1226      } else if (RC == &Hexagon::PredRegsRegClass) {
1227        // Do the transfer.
1228        SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1229                                              SDValue(Arg, 0));
1230        Ops.push_back(SDValue(PdRs,0));
1231      } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
1232        // This is immediate operand. Lower it here making sure that we DO have
1233        // const SDNode for immediate value.
1234        int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
1235        SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
1236        Ops.push_back(SDVal);
1237      } else {
1238        llvm_unreachable("Unimplemented");
1239      }
1240    }
1241    EVT ReturnValueVT = N->getValueType(0);
1242    SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
1243                                            ReturnValueVT, Ops);
1244    ReplaceUses(N, Result);
1245    return Result;
1246  }
1247  return SelectCode(N);
1248}
1249
1250//
1251// Map floating point constant values.
1252//
1253SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1254  DebugLoc dl = N->getDebugLoc();
1255  ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1256  APFloat APF = CN->getValueAPF();
1257  if (N->getValueType(0) == MVT::f32) {
1258    return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1259              CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1260  }
1261  else if (N->getValueType(0) == MVT::f64) {
1262    return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1263              CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1264  }
1265
1266  return SelectCode(N);
1267}
1268
1269
1270//
1271// Map predicate true (encoded as -1 in LLVM) to a XOR.
1272//
1273SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1274  DebugLoc dl = N->getDebugLoc();
1275  if (N->getValueType(0) == MVT::i1) {
1276    SDNode* Result;
1277    int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1278    if (Val == -1) {
1279      // Create the IntReg = 1 node.
1280      SDNode* IntRegTFR =
1281        CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1282                               CurDAG->getTargetConstant(0, MVT::i32));
1283
1284      // Pd = IntReg
1285      SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1286                                          SDValue(IntRegTFR, 0));
1287
1288      // not(Pd)
1289      SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
1290                                             SDValue(Pd, 0));
1291
1292      // xor(not(Pd))
1293      Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1294                                      SDValue(Pd, 0), SDValue(NotPd, 0));
1295
1296      // We have just built:
1297      // Rs = Pd
1298      // Pd = xor(not(Pd), Pd)
1299
1300      ReplaceUses(N, Result);
1301      return Result;
1302    }
1303  }
1304
1305  return SelectCode(N);
1306}
1307
1308
1309//
1310// Map add followed by a asr -> asr +=.
1311//
1312SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1313  DebugLoc dl = N->getDebugLoc();
1314  if (N->getValueType(0) != MVT::i32) {
1315    return SelectCode(N);
1316  }
1317  // Identify nodes of the form: add(asr(...)).
1318  SDNode* Src1 = N->getOperand(0).getNode();
1319  if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1320      || Src1->getValueType(0) != MVT::i32) {
1321    return SelectCode(N);
1322  }
1323
1324  // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1325  // Rd and Rd' are assigned to the same register
1326  SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
1327                                          N->getOperand(1),
1328                                          Src1->getOperand(0),
1329                                          Src1->getOperand(1));
1330  ReplaceUses(N, Result);
1331
1332  return Result;
1333}
1334
1335
1336SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1337  if (N->isMachineOpcode()) {
1338    N->setNodeId(-1);
1339    return NULL;   // Already selected.
1340  }
1341
1342
1343  switch (N->getOpcode()) {
1344  case ISD::Constant:
1345    return SelectConstant(N);
1346
1347  case ISD::ConstantFP:
1348    return SelectConstantFP(N);
1349
1350  case ISD::ADD:
1351    return SelectAdd(N);
1352
1353  case ISD::SHL:
1354    return SelectSHL(N);
1355
1356  case ISD::LOAD:
1357    return SelectLoad(N);
1358
1359  case ISD::STORE:
1360    return SelectStore(N);
1361
1362  case ISD::SELECT:
1363    return SelectSelect(N);
1364
1365  case ISD::TRUNCATE:
1366    return SelectTruncate(N);
1367
1368  case ISD::MUL:
1369    return SelectMul(N);
1370
1371  case ISD::ZERO_EXTEND:
1372    return SelectZeroExtend(N);
1373
1374  case ISD::INTRINSIC_WO_CHAIN:
1375    return SelectIntrinsicWOChain(N);
1376  }
1377
1378  return SelectCode(N);
1379}
1380
1381
1382//
1383// Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1384// to define these instructions.
1385//
1386bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1387                                       SDValue &Offset) {
1388  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1389      Addr.getOpcode() == ISD::TargetGlobalAddress)
1390    return false;  // Direct calls.
1391
1392  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1393    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1394    Offset = CurDAG->getTargetConstant(0, MVT::i32);
1395    return true;
1396  }
1397  Base = Addr;
1398  Offset = CurDAG->getTargetConstant(0, MVT::i32);
1399  return true;
1400}
1401
1402
1403bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1404                                            SDValue &Offset) {
1405  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1406      Addr.getOpcode() == ISD::TargetGlobalAddress)
1407    return false;  // Direct calls.
1408
1409  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1410    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1411    Offset = CurDAG->getTargetConstant(0, MVT::i32);
1412    return (IsS11_0_Offset(Offset.getNode()));
1413  }
1414  Base = Addr;
1415  Offset = CurDAG->getTargetConstant(0, MVT::i32);
1416  return (IsS11_0_Offset(Offset.getNode()));
1417}
1418
1419
1420bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1421                                            SDValue &Offset) {
1422  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1423      Addr.getOpcode() == ISD::TargetGlobalAddress)
1424    return false;  // Direct calls.
1425
1426  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1427    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1428    Offset = CurDAG->getTargetConstant(0, MVT::i32);
1429    return (IsS11_1_Offset(Offset.getNode()));
1430  }
1431  Base = Addr;
1432  Offset = CurDAG->getTargetConstant(0, MVT::i32);
1433  return (IsS11_1_Offset(Offset.getNode()));
1434}
1435
1436
1437bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1438                                            SDValue &Offset) {
1439  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1440      Addr.getOpcode() == ISD::TargetGlobalAddress)
1441    return false;  // Direct calls.
1442
1443  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1444    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1445    Offset = CurDAG->getTargetConstant(0, MVT::i32);
1446    return (IsS11_2_Offset(Offset.getNode()));
1447  }
1448  Base = Addr;
1449  Offset = CurDAG->getTargetConstant(0, MVT::i32);
1450  return (IsS11_2_Offset(Offset.getNode()));
1451}
1452
1453
1454bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1455                                            SDValue &Offset) {
1456  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1457      Addr.getOpcode() == ISD::TargetGlobalAddress)
1458    return false;  // Direct calls.
1459
1460  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1461    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1462    Offset = CurDAG->getTargetConstant(0, MVT::i32);
1463    return (IsU6_0_Offset(Offset.getNode()));
1464  }
1465  Base = Addr;
1466  Offset = CurDAG->getTargetConstant(0, MVT::i32);
1467  return (IsU6_0_Offset(Offset.getNode()));
1468}
1469
1470
1471bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1472                                            SDValue &Offset) {
1473  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1474      Addr.getOpcode() == ISD::TargetGlobalAddress)
1475    return false;  // Direct calls.
1476
1477  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1478    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1479    Offset = CurDAG->getTargetConstant(0, MVT::i32);
1480    return (IsU6_1_Offset(Offset.getNode()));
1481  }
1482  Base = Addr;
1483  Offset = CurDAG->getTargetConstant(0, MVT::i32);
1484  return (IsU6_1_Offset(Offset.getNode()));
1485}
1486
1487
1488bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1489                                            SDValue &Offset) {
1490  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1491      Addr.getOpcode() == ISD::TargetGlobalAddress)
1492    return false;  // Direct calls.
1493
1494  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1495    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1496    Offset = CurDAG->getTargetConstant(0, MVT::i32);
1497    return (IsU6_2_Offset(Offset.getNode()));
1498  }
1499  Base = Addr;
1500  Offset = CurDAG->getTargetConstant(0, MVT::i32);
1501  return (IsU6_2_Offset(Offset.getNode()));
1502}
1503
1504
1505bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1506                                           SDValue &Offset) {
1507
1508  if (Addr.getOpcode() != ISD::ADD) {
1509    return(SelectADDRriS11_2(Addr, Base, Offset));
1510  }
1511
1512  return SelectADDRriS11_2(Addr, Base, Offset);
1513}
1514
1515
1516bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1517                                            SDValue &Offset) {
1518  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1519      Addr.getOpcode() == ISD::TargetGlobalAddress)
1520    return false;  // Direct calls.
1521
1522  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1523    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1524    Offset = CurDAG->getTargetConstant(0, MVT::i32);
1525    return (IsS11_3_Offset(Offset.getNode()));
1526  }
1527  Base = Addr;
1528  Offset = CurDAG->getTargetConstant(0, MVT::i32);
1529  return (IsS11_3_Offset(Offset.getNode()));
1530}
1531
1532bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1533                                       SDValue &R2) {
1534  if (Addr.getOpcode() == ISD::FrameIndex) return false;
1535  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1536      Addr.getOpcode() == ISD::TargetGlobalAddress)
1537    return false;  // Direct calls.
1538
1539  if (Addr.getOpcode() == ISD::ADD) {
1540    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1541      if (isInt<13>(CN->getSExtValue()))
1542        return false;  // Let the reg+imm pattern catch this!
1543    R1 = Addr.getOperand(0);
1544    R2 = Addr.getOperand(1);
1545    return true;
1546  }
1547
1548  R1 = Addr;
1549
1550  return true;
1551}
1552
1553
1554// Handle generic address case. It is accessed from inlined asm =m constraints,
1555// which could have any kind of pointer.
1556bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1557                                          SDValue &Base, SDValue &Offset) {
1558  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1559      Addr.getOpcode() == ISD::TargetGlobalAddress)
1560    return false;  // Direct calls.
1561
1562  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1563    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1564    Offset = CurDAG->getTargetConstant(0, MVT::i32);
1565    return true;
1566  }
1567
1568  if (Addr.getOpcode() == ISD::ADD) {
1569    Base = Addr.getOperand(0);
1570    Offset = Addr.getOperand(1);
1571    return true;
1572  }
1573
1574  Base = Addr;
1575  Offset = CurDAG->getTargetConstant(0, MVT::i32);
1576  return true;
1577}
1578
1579
1580bool HexagonDAGToDAGISel::
1581SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1582                             std::vector<SDValue> &OutOps) {
1583  SDValue Op0, Op1;
1584
1585  switch (ConstraintCode) {
1586  case 'o':   // Offsetable.
1587  case 'v':   // Not offsetable.
1588  default: return true;
1589  case 'm':   // Memory.
1590    if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1591      return true;
1592    break;
1593  }
1594
1595  OutOps.push_back(Op0);
1596  OutOps.push_back(Op1);
1597  return false;
1598}
1599
1600bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
1601  unsigned UseCount = 0;
1602  for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
1603    UseCount++;
1604  }
1605
1606  return (UseCount <= 1);
1607
1608}
1609
1610//===--------------------------------------------------------------------===//
1611// Return 'true' if use count of the global address is below threshold.
1612//===--------------------------------------------------------------------===//
1613bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const {
1614  assert(N->getOpcode() == ISD::TargetGlobalAddress &&
1615         "Expecting a target global address");
1616
1617  // Always try to fold the address.
1618  if (TM.getOptLevel() == CodeGenOpt::Aggressive)
1619    return true;
1620
1621  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
1622  DenseMap<const GlobalValue *, unsigned>::const_iterator GI =
1623    GlobalAddressUseCountMap.find(GA->getGlobal());
1624
1625  if (GI == GlobalAddressUseCountMap.end())
1626    return false;
1627
1628  return GI->second <= MaxNumOfUsesForConstExtenders;
1629}
1630
1631//===--------------------------------------------------------------------===//
1632// Return true if the non GP-relative global address can be folded.
1633//===--------------------------------------------------------------------===//
1634inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
1635  return foldGlobalAddressImpl(N, R, false);
1636}
1637
1638//===--------------------------------------------------------------------===//
1639// Return true if the GP-relative global address can be folded.
1640//===--------------------------------------------------------------------===//
1641inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
1642  return foldGlobalAddressImpl(N, R, true);
1643}
1644
1645//===--------------------------------------------------------------------===//
1646// Fold offset of the global address if number of uses are below threshold.
1647//===--------------------------------------------------------------------===//
1648bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
1649                                                bool ShouldLookForGP) {
1650  if (N.getOpcode() == ISD::ADD) {
1651    SDValue N0 = N.getOperand(0);
1652    SDValue N1 = N.getOperand(1);
1653    if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
1654        (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
1655      ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
1656      GlobalAddressSDNode *GA =
1657        dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
1658
1659      if (Const && GA &&
1660          (GA->getOpcode() == ISD::TargetGlobalAddress)) {
1661        if ((N0.getOpcode() == HexagonISD::CONST32) &&
1662                !hasNumUsesBelowThresGA(GA))
1663            return false;
1664        R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
1665                                          Const->getDebugLoc(),
1666                                          N.getValueType(),
1667                                          GA->getOffset() +
1668                                          (uint64_t)Const->getSExtValue());
1669        return true;
1670      }
1671    }
1672  }
1673  return false;
1674}
1675