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