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