LLVM API Documentation

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