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