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