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