Hexagon V5 FP 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 *SelectIntrinsicWChain(SDNode *N);
94   SDNode *SelectConstant(SDNode *N);
95   SDNode *SelectConstantFP(SDNode *N);
96   SDNode *SelectAdd(SDNode *N);
97
98   // Include the pieces autogenerated from the target description.
99 #include "HexagonGenDAGISel.inc"
100 };
101 }  // end anonymous namespace
102
103
104 /// createHexagonISelDag - This pass converts a legalized DAG into a
105 /// Hexagon-specific DAG, ready for instruction scheduling.
106 ///
107 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM) {
108   return new HexagonDAGToDAGISel(TM);
109 }
110
111 static bool IsS11_0_Offset(SDNode * S) {
112     ConstantSDNode *N = cast<ConstantSDNode>(S);
113
114   // immS16 predicate - True if the immediate fits in a 16-bit sign extended
115   // field.
116   int64_t v = (int64_t)N->getSExtValue();
117   return isInt<11>(v);
118 }
119
120
121 static bool IsS11_1_Offset(SDNode * S) {
122     ConstantSDNode *N = cast<ConstantSDNode>(S);
123
124   // immS16 predicate - True if the immediate fits in a 16-bit sign extended
125   // field.
126   int64_t v = (int64_t)N->getSExtValue();
127   return isShiftedInt<11,1>(v);
128 }
129
130
131 static bool IsS11_2_Offset(SDNode * S) {
132     ConstantSDNode *N = cast<ConstantSDNode>(S);
133
134   // immS16 predicate - True if the immediate fits in a 16-bit sign extended
135   // field.
136   int64_t v = (int64_t)N->getSExtValue();
137   return isShiftedInt<11,2>(v);
138 }
139
140
141 static bool IsS11_3_Offset(SDNode * S) {
142     ConstantSDNode *N = cast<ConstantSDNode>(S);
143
144   // immS16 predicate - True if the immediate fits in a 16-bit sign extended
145   // field.
146   int64_t v = (int64_t)N->getSExtValue();
147   return isShiftedInt<11,3>(v);
148 }
149
150
151 static bool IsU6_0_Offset(SDNode * S) {
152     ConstantSDNode *N = cast<ConstantSDNode>(S);
153
154   // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
155   // field.
156   int64_t v = (int64_t)N->getSExtValue();
157   return isUInt<6>(v);
158 }
159
160
161 static bool IsU6_1_Offset(SDNode * S) {
162     ConstantSDNode *N = cast<ConstantSDNode>(S);
163
164   // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
165   // field.
166   int64_t v = (int64_t)N->getSExtValue();
167   return isShiftedUInt<6,1>(v);
168 }
169
170
171 static bool IsU6_2_Offset(SDNode * S) {
172     ConstantSDNode *N = cast<ConstantSDNode>(S);
173
174   // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
175   // field.
176   int64_t v = (int64_t)N->getSExtValue();
177   return isShiftedUInt<6,2>(v);
178 }
179
180
181 // Intrinsics that return a a predicate.
182 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
183 {
184   switch (ID) {
185     default:
186       return 0;
187     case Intrinsic::hexagon_C2_cmpeq:
188     case Intrinsic::hexagon_C2_cmpgt:
189     case Intrinsic::hexagon_C2_cmpgtu:
190     case Intrinsic::hexagon_C2_cmpgtup:
191     case Intrinsic::hexagon_C2_cmpgtp:
192     case Intrinsic::hexagon_C2_cmpeqp:
193     case Intrinsic::hexagon_C2_bitsset:
194     case Intrinsic::hexagon_C2_bitsclr:
195     case Intrinsic::hexagon_C2_cmpeqi:
196     case Intrinsic::hexagon_C2_cmpgti:
197     case Intrinsic::hexagon_C2_cmpgtui:
198     case Intrinsic::hexagon_C2_cmpgei:
199     case Intrinsic::hexagon_C2_cmpgeui:
200     case Intrinsic::hexagon_C2_cmplt:
201     case Intrinsic::hexagon_C2_cmpltu:
202     case Intrinsic::hexagon_C2_bitsclri:
203     case Intrinsic::hexagon_C2_and:
204     case Intrinsic::hexagon_C2_or:
205     case Intrinsic::hexagon_C2_xor:
206     case Intrinsic::hexagon_C2_andn:
207     case Intrinsic::hexagon_C2_not:
208     case Intrinsic::hexagon_C2_orn:
209     case Intrinsic::hexagon_C2_pxfer_map:
210     case Intrinsic::hexagon_C2_any8:
211     case Intrinsic::hexagon_C2_all8:
212     case Intrinsic::hexagon_A2_vcmpbeq:
213     case Intrinsic::hexagon_A2_vcmpbgtu:
214     case Intrinsic::hexagon_A2_vcmpheq:
215     case Intrinsic::hexagon_A2_vcmphgt:
216     case Intrinsic::hexagon_A2_vcmphgtu:
217     case Intrinsic::hexagon_A2_vcmpweq:
218     case Intrinsic::hexagon_A2_vcmpwgt:
219     case Intrinsic::hexagon_A2_vcmpwgtu:
220     case Intrinsic::hexagon_C2_tfrrp:
221     case Intrinsic::hexagon_S2_tstbit_i:
222     case Intrinsic::hexagon_S2_tstbit_r:
223       return 1;
224   }
225 }
226
227
228 // Intrinsics that have predicate operands.
229 static unsigned doesIntrinsicContainPredicate(unsigned ID)
230 {
231   switch (ID) {
232     default:
233       return 0;
234     case Intrinsic::hexagon_C2_tfrpr:
235       return Hexagon::TFR_RsPd;
236     case Intrinsic::hexagon_C2_and:
237       return Hexagon::AND_pp;
238     case Intrinsic::hexagon_C2_xor:
239       return Hexagon::XOR_pp;
240     case Intrinsic::hexagon_C2_or:
241       return Hexagon::OR_pp;
242     case Intrinsic::hexagon_C2_not:
243       return Hexagon::NOT_p;
244     case Intrinsic::hexagon_C2_any8:
245       return Hexagon::ANY_pp;
246     case Intrinsic::hexagon_C2_all8:
247       return Hexagon::ALL_pp;
248     case Intrinsic::hexagon_C2_vitpack:
249       return Hexagon::VITPACK_pp;
250     case Intrinsic::hexagon_C2_mask:
251       return Hexagon::MASK_p;
252     case Intrinsic::hexagon_C2_mux:
253       return Hexagon::MUX_rr;
254
255       // Mapping hexagon_C2_muxir to MUX_pri.  This is pretty weird - but
256       // that's how it's mapped in q6protos.h.
257     case Intrinsic::hexagon_C2_muxir:
258       return Hexagon::MUX_ri;
259
260       // Mapping hexagon_C2_muxri to MUX_pir.  This is pretty weird - but
261       // that's how it's mapped in q6protos.h.
262     case Intrinsic::hexagon_C2_muxri:
263       return Hexagon::MUX_ir;
264
265     case Intrinsic::hexagon_C2_muxii:
266       return Hexagon::MUX_ii;
267     case Intrinsic::hexagon_C2_vmux:
268       return Hexagon::VMUX_prr64;
269     case Intrinsic::hexagon_S2_valignrb:
270       return Hexagon::VALIGN_rrp;
271     case Intrinsic::hexagon_S2_vsplicerb:
272       return Hexagon::VSPLICE_rrp;
273   }
274 }
275
276
277 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
278   if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
279     return true;
280   }
281   if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
282     return true;
283   }
284   if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
285     return true;
286   }
287   if (MemType == MVT::i8 && isInt<11>(Offset)) {
288     return true;
289   }
290   return false;
291 }
292
293
294 //
295 // Try to lower loads of GlobalAdresses into base+offset loads.  Custom
296 // lowering for GlobalAddress nodes has already turned it into a
297 // CONST32.
298 //
299 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
300   SDValue Chain = LD->getChain();
301   SDNode* Const32 = LD->getBasePtr().getNode();
302   unsigned Opcode = 0;
303
304   if (Const32->getOpcode() == HexagonISD::CONST32 &&
305       ISD::isNormalLoad(LD)) {
306     SDValue Base = Const32->getOperand(0);
307     EVT LoadedVT = LD->getMemoryVT();
308     int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
309     if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
310       MVT PointerTy = TLI.getPointerTy();
311       const GlobalValue* GV =
312         cast<GlobalAddressSDNode>(Base)->getGlobal();
313       SDValue TargAddr =
314         CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
315       SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
316                                                dl, PointerTy,
317                                                TargAddr);
318       // Figure out base + offset opcode
319       if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
320       else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
321       else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
322       else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
323       else llvm_unreachable("unknown memory type");
324
325       // Build indexed load.
326       SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
327       SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
328                                               LD->getValueType(0),
329                                               MVT::Other,
330                                               SDValue(NewBase,0),
331                                               TargetConstOff,
332                                               Chain);
333       MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
334       MemOp[0] = LD->getMemOperand();
335       cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
336       ReplaceUses(LD, Result);
337       return Result;
338     }
339   }
340
341   return SelectCode(LD);
342 }
343
344
345 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
346                                                            unsigned Opcode,
347                                                            DebugLoc dl)
348 {
349   SDValue Chain = LD->getChain();
350   EVT LoadedVT = LD->getMemoryVT();
351   SDValue Base = LD->getBasePtr();
352   SDValue Offset = LD->getOffset();
353   SDNode *OffsetNode = Offset.getNode();
354   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
355   SDValue N1 = LD->getOperand(1);
356   SDValue CPTmpN1_0;
357   SDValue CPTmpN1_1;
358   if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
359       N1.getNode()->getValueType(0) == MVT::i32) {
360     if (TII->isValidAutoIncImm(LoadedVT, Val)) {
361       SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
362       SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
363                                                 MVT::Other, Base, TargetConst,
364                                                 Chain);
365       SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
366                                                 SDValue(Result_1, 0));
367       MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
368       MemOp[0] = LD->getMemOperand();
369       cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
370       const SDValue Froms[] = { SDValue(LD, 0),
371                                 SDValue(LD, 1),
372                                 SDValue(LD, 2)
373       };
374       const SDValue Tos[]   = { SDValue(Result_2, 0),
375                                 SDValue(Result_1, 1),
376                                 SDValue(Result_1, 2)
377       };
378       ReplaceUses(Froms, Tos, 3);
379       return Result_2;
380     }
381     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
382     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
383     SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
384                                               MVT::Other, Base, TargetConst0,
385                                               Chain);
386     SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
387                                                 MVT::i64, SDValue(Result_1, 0));
388     SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
389                                               MVT::i32, Base, TargetConstVal,
390                                                 SDValue(Result_1, 1));
391     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
392     MemOp[0] = LD->getMemOperand();
393     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
394     const SDValue Froms[] = { SDValue(LD, 0),
395                               SDValue(LD, 1),
396                               SDValue(LD, 2)
397     };
398     const SDValue Tos[]   = { SDValue(Result_2, 0),
399                               SDValue(Result_3, 0),
400                               SDValue(Result_1, 1)
401     };
402     ReplaceUses(Froms, Tos, 3);
403     return Result_2;
404   }
405   return SelectCode(LD);
406 }
407
408
409 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
410                                                            unsigned Opcode,
411                                                            DebugLoc dl)
412 {
413   SDValue Chain = LD->getChain();
414   EVT LoadedVT = LD->getMemoryVT();
415   SDValue Base = LD->getBasePtr();
416   SDValue Offset = LD->getOffset();
417   SDNode *OffsetNode = Offset.getNode();
418   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
419   SDValue N1 = LD->getOperand(1);
420   SDValue CPTmpN1_0;
421   SDValue CPTmpN1_1;
422   if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
423       N1.getNode()->getValueType(0) == MVT::i32) {
424     if (TII->isValidAutoIncImm(LoadedVT, Val)) {
425       SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
426       SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
427       SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
428                                                 MVT::i32, MVT::Other, Base,
429                                                 TargetConstVal, Chain);
430       SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
431                                                 TargetConst0);
432       SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
433                                                 MVT::i64, MVT::Other,
434                                                 SDValue(Result_2,0),
435                                                 SDValue(Result_1,0));
436       MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
437       MemOp[0] = LD->getMemOperand();
438       cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
439       const SDValue Froms[] = { SDValue(LD, 0),
440                                 SDValue(LD, 1),
441                                 SDValue(LD, 2)
442       };
443       const SDValue Tos[]   = { SDValue(Result_3, 0),
444                                 SDValue(Result_1, 1),
445                                 SDValue(Result_1, 2)
446       };
447       ReplaceUses(Froms, Tos, 3);
448       return Result_3;
449     }
450
451     // Generate an indirect load.
452     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
453     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
454     SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
455                                               MVT::Other,
456                                               Base, TargetConst0, Chain);
457     SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
458                                               TargetConst0);
459     SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
460                                               MVT::i64, MVT::Other,
461                                               SDValue(Result_2,0),
462                                               SDValue(Result_1,0));
463     // Add offset to base.
464     SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
465                                               Base, TargetConstVal,
466                                               SDValue(Result_1, 1));
467     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
468     MemOp[0] = LD->getMemOperand();
469     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
470     const SDValue Froms[] = { SDValue(LD, 0),
471                               SDValue(LD, 1),
472                               SDValue(LD, 2)
473     };
474     const SDValue Tos[]   = { SDValue(Result_3, 0), // Load value.
475                               SDValue(Result_4, 0), // New address.
476                               SDValue(Result_1, 1)
477     };
478     ReplaceUses(Froms, Tos, 3);
479     return Result_3;
480   }
481
482   return SelectCode(LD);
483 }
484
485
486 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
487   SDValue Chain = LD->getChain();
488   SDValue Base = LD->getBasePtr();
489   SDValue Offset = LD->getOffset();
490   SDNode *OffsetNode = Offset.getNode();
491   // Get the constant value.
492   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
493   EVT LoadedVT = LD->getMemoryVT();
494   unsigned Opcode = 0;
495
496   // Check for zero ext loads.
497   bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
498
499   // Figure out the opcode.
500   if (LoadedVT == MVT::i64) {
501     if (TII->isValidAutoIncImm(LoadedVT, Val))
502       Opcode = Hexagon::POST_LDrid;
503     else
504       Opcode = Hexagon::LDrid;
505   } else if (LoadedVT == MVT::i32) {
506     if (TII->isValidAutoIncImm(LoadedVT, Val))
507       Opcode = Hexagon::POST_LDriw;
508     else
509       Opcode = Hexagon::LDriw;
510   } else if (LoadedVT == MVT::i16) {
511     if (TII->isValidAutoIncImm(LoadedVT, Val))
512       Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
513     else
514       Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
515   } else if (LoadedVT == MVT::i8) {
516     if (TII->isValidAutoIncImm(LoadedVT, Val))
517       Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
518     else
519       Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
520   } else
521     llvm_unreachable("unknown memory type");
522
523   // For zero ext i64 loads, we need to add combine instructions.
524   if (LD->getValueType(0) == MVT::i64 &&
525       LD->getExtensionType() == ISD::ZEXTLOAD) {
526     return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
527   }
528   if (LD->getValueType(0) == MVT::i64 &&
529              LD->getExtensionType() == ISD::SEXTLOAD) {
530     // Handle sign ext i64 loads.
531     return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
532   }
533   if (TII->isValidAutoIncImm(LoadedVT, Val)) {
534     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
535     SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
536                                             LD->getValueType(0),
537                                             MVT::i32, MVT::Other, Base,
538                                             TargetConstVal, Chain);
539     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
540     MemOp[0] = LD->getMemOperand();
541     cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
542     const SDValue Froms[] = { SDValue(LD, 0),
543                               SDValue(LD, 1),
544                               SDValue(LD, 2)
545     };
546     const SDValue Tos[]   = { SDValue(Result, 0),
547                               SDValue(Result, 1),
548                               SDValue(Result, 2)
549     };
550     ReplaceUses(Froms, Tos, 3);
551     return Result;
552   } else {
553     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
554     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
555     SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
556                                               LD->getValueType(0),
557                                               MVT::Other, Base, TargetConst0,
558                                               Chain);
559     SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
560                                               Base, TargetConstVal,
561                                               SDValue(Result_1, 1));
562     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
563     MemOp[0] = LD->getMemOperand();
564     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
565     const SDValue Froms[] = { SDValue(LD, 0),
566                               SDValue(LD, 1),
567                               SDValue(LD, 2)
568     };
569     const SDValue Tos[]   = { SDValue(Result_1, 0),
570                               SDValue(Result_2, 0),
571                               SDValue(Result_1, 1)
572     };
573     ReplaceUses(Froms, Tos, 3);
574     return Result_1;
575   }
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 llvm_unreachable("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_indexed;
642   else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
643   else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
644   else llvm_unreachable("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 llvm_unreachable("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         return 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         return 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       llvm_unreachable("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, *MF);
1134
1135       if (RC == &Hexagon::IntRegsRegClass ||
1136           RC == &Hexagon::DoubleRegsRegClass) {
1137         Ops.push_back(SDValue(Arg, 0));
1138       } else if (RC == &Hexagon::PredRegsRegClass) {
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         llvm_unreachable("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 // Map floating point constant values.
1165 //
1166 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1167   DebugLoc dl = N->getDebugLoc();
1168   ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1169   APFloat APF = CN->getValueAPF();
1170   if (N->getValueType(0) == MVT::f32) {
1171     return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1172               CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1173   }
1174   else if (N->getValueType(0) == MVT::f64) {
1175     return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1176               CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1177   }
1178
1179   return SelectCode(N);
1180 }
1181
1182
1183 //
1184 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1185 //
1186 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1187   DebugLoc dl = N->getDebugLoc();
1188   if (N->getValueType(0) == MVT::i1) {
1189     SDNode* Result;
1190     int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1191     if (Val == -1) {
1192       // Create the IntReg = 1 node.
1193       SDNode* IntRegTFR =
1194         CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1195                                CurDAG->getTargetConstant(0, MVT::i32));
1196
1197       // Pd = IntReg
1198       SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1199                                           SDValue(IntRegTFR, 0));
1200
1201       // not(Pd)
1202       SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
1203                                              SDValue(Pd, 0));
1204
1205       // xor(not(Pd))
1206       Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1207                                       SDValue(Pd, 0), SDValue(NotPd, 0));
1208
1209       // We have just built:
1210       // Rs = Pd
1211       // Pd = xor(not(Pd), Pd)
1212
1213       ReplaceUses(N, Result);
1214       return Result;
1215     }
1216   }
1217
1218   return SelectCode(N);
1219 }
1220
1221
1222 //
1223 // Map add followed by a asr -> asr +=.
1224 //
1225 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1226   DebugLoc dl = N->getDebugLoc();
1227   if (N->getValueType(0) != MVT::i32) {
1228     return SelectCode(N);
1229   }
1230   // Identify nodes of the form: add(asr(...)).
1231   SDNode* Src1 = N->getOperand(0).getNode();
1232   if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1233       || Src1->getValueType(0) != MVT::i32) {
1234     return SelectCode(N);
1235   }
1236
1237   // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1238   // Rd and Rd' are assigned to the same register
1239   SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
1240                                           N->getOperand(1),
1241                                           Src1->getOperand(0),
1242                                           Src1->getOperand(1));
1243   ReplaceUses(N, Result);
1244
1245   return Result;
1246 }
1247
1248
1249 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1250   if (N->isMachineOpcode())
1251     return NULL;   // Already selected.
1252
1253
1254   switch (N->getOpcode()) {
1255   case ISD::Constant:
1256     return SelectConstant(N);
1257
1258   case ISD::ConstantFP:
1259     return SelectConstantFP(N);
1260
1261   case ISD::ADD:
1262     return SelectAdd(N);
1263
1264   case ISD::SHL:
1265     return SelectSHL(N);
1266
1267   case ISD::LOAD:
1268     return SelectLoad(N);
1269
1270   case ISD::STORE:
1271     return SelectStore(N);
1272
1273   case ISD::SELECT:
1274     return SelectSelect(N);
1275
1276   case ISD::TRUNCATE:
1277     return SelectTruncate(N);
1278
1279   case ISD::MUL:
1280     return SelectMul(N);
1281
1282   case ISD::ZERO_EXTEND:
1283     return SelectZeroExtend(N);
1284
1285   case ISD::INTRINSIC_WO_CHAIN:
1286     return SelectIntrinsicWOChain(N);
1287   }
1288
1289   return SelectCode(N);
1290 }
1291
1292
1293 //
1294 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1295 // to define these instructions.
1296 //
1297 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1298                                        SDValue &Offset) {
1299   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1300       Addr.getOpcode() == ISD::TargetGlobalAddress)
1301     return false;  // Direct calls.
1302
1303   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1304     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1305     Offset = CurDAG->getTargetConstant(0, MVT::i32);
1306     return true;
1307   }
1308   Base = Addr;
1309   Offset = CurDAG->getTargetConstant(0, MVT::i32);
1310   return true;
1311 }
1312
1313
1314 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1315                                             SDValue &Offset) {
1316   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1317       Addr.getOpcode() == ISD::TargetGlobalAddress)
1318     return false;  // Direct calls.
1319
1320   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1321     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1322     Offset = CurDAG->getTargetConstant(0, MVT::i32);
1323     return (IsS11_0_Offset(Offset.getNode()));
1324   }
1325   Base = Addr;
1326   Offset = CurDAG->getTargetConstant(0, MVT::i32);
1327   return (IsS11_0_Offset(Offset.getNode()));
1328 }
1329
1330
1331 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1332                                             SDValue &Offset) {
1333   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1334       Addr.getOpcode() == ISD::TargetGlobalAddress)
1335     return false;  // Direct calls.
1336
1337   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1338     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1339     Offset = CurDAG->getTargetConstant(0, MVT::i32);
1340     return (IsS11_1_Offset(Offset.getNode()));
1341   }
1342   Base = Addr;
1343   Offset = CurDAG->getTargetConstant(0, MVT::i32);
1344   return (IsS11_1_Offset(Offset.getNode()));
1345 }
1346
1347
1348 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1349                                             SDValue &Offset) {
1350   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1351       Addr.getOpcode() == ISD::TargetGlobalAddress)
1352     return false;  // Direct calls.
1353
1354   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1355     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1356     Offset = CurDAG->getTargetConstant(0, MVT::i32);
1357     return (IsS11_2_Offset(Offset.getNode()));
1358   }
1359   Base = Addr;
1360   Offset = CurDAG->getTargetConstant(0, MVT::i32);
1361   return (IsS11_2_Offset(Offset.getNode()));
1362 }
1363
1364
1365 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1366                                             SDValue &Offset) {
1367   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1368       Addr.getOpcode() == ISD::TargetGlobalAddress)
1369     return false;  // Direct calls.
1370
1371   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1372     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1373     Offset = CurDAG->getTargetConstant(0, MVT::i32);
1374     return (IsU6_0_Offset(Offset.getNode()));
1375   }
1376   Base = Addr;
1377   Offset = CurDAG->getTargetConstant(0, MVT::i32);
1378   return (IsU6_0_Offset(Offset.getNode()));
1379 }
1380
1381
1382 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1383                                             SDValue &Offset) {
1384   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1385       Addr.getOpcode() == ISD::TargetGlobalAddress)
1386     return false;  // Direct calls.
1387
1388   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1389     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1390     Offset = CurDAG->getTargetConstant(0, MVT::i32);
1391     return (IsU6_1_Offset(Offset.getNode()));
1392   }
1393   Base = Addr;
1394   Offset = CurDAG->getTargetConstant(0, MVT::i32);
1395   return (IsU6_1_Offset(Offset.getNode()));
1396 }
1397
1398
1399 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1400                                             SDValue &Offset) {
1401   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1402       Addr.getOpcode() == ISD::TargetGlobalAddress)
1403     return false;  // Direct calls.
1404
1405   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1406     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1407     Offset = CurDAG->getTargetConstant(0, MVT::i32);
1408     return (IsU6_2_Offset(Offset.getNode()));
1409   }
1410   Base = Addr;
1411   Offset = CurDAG->getTargetConstant(0, MVT::i32);
1412   return (IsU6_2_Offset(Offset.getNode()));
1413 }
1414
1415
1416 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1417                                            SDValue &Offset) {
1418
1419   if (Addr.getOpcode() != ISD::ADD) {
1420     return(SelectADDRriS11_2(Addr, Base, Offset));
1421   }
1422
1423   return SelectADDRriS11_2(Addr, Base, Offset);
1424 }
1425
1426
1427 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1428                                             SDValue &Offset) {
1429   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1430       Addr.getOpcode() == ISD::TargetGlobalAddress)
1431     return false;  // Direct calls.
1432
1433   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1434     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1435     Offset = CurDAG->getTargetConstant(0, MVT::i32);
1436     return (IsS11_3_Offset(Offset.getNode()));
1437   }
1438   Base = Addr;
1439   Offset = CurDAG->getTargetConstant(0, MVT::i32);
1440   return (IsS11_3_Offset(Offset.getNode()));
1441 }
1442
1443 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1444                                        SDValue &R2) {
1445   if (Addr.getOpcode() == ISD::FrameIndex) return false;
1446   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1447       Addr.getOpcode() == ISD::TargetGlobalAddress)
1448     return false;  // Direct calls.
1449
1450   if (Addr.getOpcode() == ISD::ADD) {
1451     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1452       if (isInt<13>(CN->getSExtValue()))
1453         return false;  // Let the reg+imm pattern catch this!
1454     R1 = Addr.getOperand(0);
1455     R2 = Addr.getOperand(1);
1456     return true;
1457   }
1458
1459   R1 = Addr;
1460
1461   return true;
1462 }
1463
1464
1465 // Handle generic address case. It is accessed from inlined asm =m constraints,
1466 // which could have any kind of pointer.
1467 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1468                                           SDValue &Base, SDValue &Offset) {
1469   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1470       Addr.getOpcode() == ISD::TargetGlobalAddress)
1471     return false;  // Direct calls.
1472
1473   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1474     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1475     Offset = CurDAG->getTargetConstant(0, MVT::i32);
1476     return true;
1477   }
1478
1479   if (Addr.getOpcode() == ISD::ADD) {
1480     Base = Addr.getOperand(0);
1481     Offset = Addr.getOperand(1);
1482     return true;
1483   }
1484
1485   Base = Addr;
1486   Offset = CurDAG->getTargetConstant(0, MVT::i32);
1487   return true;
1488 }
1489
1490
1491 bool HexagonDAGToDAGISel::
1492 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1493                              std::vector<SDValue> &OutOps) {
1494   SDValue Op0, Op1;
1495
1496   switch (ConstraintCode) {
1497   case 'o':   // Offsetable.
1498   case 'v':   // Not offsetable.
1499   default: return true;
1500   case 'm':   // Memory.
1501     if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1502       return true;
1503     break;
1504   }
1505
1506   OutOps.push_back(Op0);
1507   OutOps.push_back(Op1);
1508   return false;
1509 }