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 #include "Hexagon.h"
15 #include "HexagonISelLowering.h"
16 #include "HexagonTargetMachine.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/CodeGen/SelectionDAGISel.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/Support/CommandLine.h"
21 #include "llvm/Support/Compiler.h"
22 #include "llvm/Support/Debug.h"
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "hexagon-isel"
26 
27 static
28 cl::opt<unsigned>
29 MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders",
30   cl::Hidden, cl::init(2),
31   cl::desc("Maximum number of uses of a global address such that we still us a"
32            "constant extended instruction"));
33 
34 //===----------------------------------------------------------------------===//
35 // Instruction Selector Implementation
36 //===----------------------------------------------------------------------===//
37 
38 namespace llvm {
39   void initializeHexagonDAGToDAGISelPass(PassRegistry&);
40 }
41 
42 //===--------------------------------------------------------------------===//
43 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
44 /// instructions for SelectionDAG operations.
45 ///
46 namespace {
47 class HexagonDAGToDAGISel : public SelectionDAGISel {
48   const HexagonTargetMachine& HTM;
49   const HexagonSubtarget *HST;
50 public:
HexagonDAGToDAGISel(HexagonTargetMachine & tm,CodeGenOpt::Level OptLevel)51   explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm,
52                                CodeGenOpt::Level OptLevel)
53       : SelectionDAGISel(tm, OptLevel), HTM(tm) {
54     initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
55   }
56 
runOnMachineFunction(MachineFunction & MF)57   bool runOnMachineFunction(MachineFunction &MF) override {
58     // Reset the subtarget each time through.
59     HST = &MF.getSubtarget<HexagonSubtarget>();
60     SelectionDAGISel::runOnMachineFunction(MF);
61     return true;
62   }
63 
64   virtual void PreprocessISelDAG() override;
65 
66   SDNode *Select(SDNode *N) override;
67 
68   // Complex Pattern Selectors.
69   inline bool SelectAddrGA(SDValue &N, SDValue &R);
70   inline bool SelectAddrGP(SDValue &N, SDValue &R);
71   bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP);
72   bool SelectAddrFI(SDValue &N, SDValue &R);
73 
getPassName() const74   const char *getPassName() const override {
75     return "Hexagon DAG->DAG Pattern Instruction Selection";
76   }
77 
78   SDNode *SelectFrameIndex(SDNode *N);
79   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
80   /// inline asm expressions.
81   bool SelectInlineAsmMemoryOperand(const SDValue &Op,
82                                     unsigned ConstraintID,
83                                     std::vector<SDValue> &OutOps) override;
84   SDNode *SelectLoad(SDNode *N);
85   SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl);
86   SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl);
87   SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
88                                         SDLoc dl);
89   SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
90                                         SDLoc dl);
91   SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl);
92   SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl);
93   SDNode *SelectStore(SDNode *N);
94   SDNode *SelectSHL(SDNode *N);
95   SDNode *SelectMul(SDNode *N);
96   SDNode *SelectZeroExtend(SDNode *N);
97   SDNode *SelectIntrinsicWChain(SDNode *N);
98   SDNode *SelectIntrinsicWOChain(SDNode *N);
99   SDNode *SelectConstant(SDNode *N);
100   SDNode *SelectConstantFP(SDNode *N);
101   SDNode *SelectAdd(SDNode *N);
102   SDNode *SelectBitOp(SDNode *N);
103 
104   // XformMskToBitPosU5Imm - Returns the bit position which
105   // the single bit 32 bit mask represents.
106   // Used in Clr and Set bit immediate memops.
XformMskToBitPosU5Imm(uint32_t Imm)107   SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
108     int32_t bitPos;
109     bitPos = Log2_32(Imm);
110     assert(bitPos >= 0 && bitPos < 32 &&
111            "Constant out of range for 32 BitPos Memops");
112     return CurDAG->getTargetConstant(bitPos, MVT::i32);
113   }
114 
115   // XformMskToBitPosU4Imm - Returns the bit position which the single-bit
116   // 16 bit mask represents. Used in Clr and Set bit immediate memops.
XformMskToBitPosU4Imm(uint16_t Imm)117   SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
118     return XformMskToBitPosU5Imm(Imm);
119   }
120 
121   // XformMskToBitPosU3Imm - Returns the bit position which the single-bit
122   // 8 bit mask represents. Used in Clr and Set bit immediate memops.
XformMskToBitPosU3Imm(uint8_t Imm)123   SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
124     return XformMskToBitPosU5Imm(Imm);
125   }
126 
127   // Return true if there is exactly one bit set in V, i.e., if V is one of the
128   // following integers: 2^0, 2^1, ..., 2^31.
ImmIsSingleBit(uint32_t v) const129   bool ImmIsSingleBit(uint32_t v) const {
130     return isPowerOf2_32(v);
131   }
132 
133   // XformM5ToU5Imm - Return a target constant with the specified value, of
134   // type i32 where the negative literal is transformed into a positive literal
135   // for use in -= memops.
XformM5ToU5Imm(signed Imm)136   inline SDValue XformM5ToU5Imm(signed Imm) {
137      assert( (Imm >= -31 && Imm <= -1)  && "Constant out of range for Memops");
138      return CurDAG->getTargetConstant( - Imm, MVT::i32);
139   }
140 
141   // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
142   // [1..128], used in cmpb.gtu instructions.
XformU7ToU7M1Imm(signed Imm)143   inline SDValue XformU7ToU7M1Imm(signed Imm) {
144     assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
145     return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
146   }
147 
148   // XformS8ToS8M1Imm - Return a target constant decremented by 1.
XformSToSM1Imm(signed Imm)149   inline SDValue XformSToSM1Imm(signed Imm) {
150     return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
151   }
152 
153   // XformU8ToU8M1Imm - Return a target constant decremented by 1.
XformUToUM1Imm(unsigned Imm)154   inline SDValue XformUToUM1Imm(unsigned Imm) {
155     assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
156     return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
157   }
158 
159   // XformSToSM2Imm - Return a target constant decremented by 2.
XformSToSM2Imm(unsigned Imm)160   inline SDValue XformSToSM2Imm(unsigned Imm) {
161     return CurDAG->getTargetConstant(Imm - 2, MVT::i32);
162   }
163 
164   // XformSToSM3Imm - Return a target constant decremented by 3.
XformSToSM3Imm(unsigned Imm)165   inline SDValue XformSToSM3Imm(unsigned Imm) {
166     return CurDAG->getTargetConstant(Imm - 3, MVT::i32);
167   }
168 
169   // Include the pieces autogenerated from the target description.
170   #include "HexagonGenDAGISel.inc"
171 
172 private:
173   bool isValueExtension(const SDValue &Val, unsigned FromBits, SDValue &Src);
174 }; // end HexagonDAGToDAGISel
175 }  // end anonymous namespace
176 
177 
178 /// createHexagonISelDag - This pass converts a legalized DAG into a
179 /// Hexagon-specific DAG, ready for instruction scheduling.
180 ///
181 namespace llvm {
createHexagonISelDag(HexagonTargetMachine & TM,CodeGenOpt::Level OptLevel)182 FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM,
183                                    CodeGenOpt::Level OptLevel) {
184   return new HexagonDAGToDAGISel(TM, OptLevel);
185 }
186 }
187 
initializePassOnce(PassRegistry & Registry)188 static void initializePassOnce(PassRegistry &Registry) {
189   const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
190   PassInfo *PI = new PassInfo(Name, "hexagon-isel",
191                               &SelectionDAGISel::ID, nullptr, false, false);
192   Registry.registerPass(*PI, true);
193 }
194 
initializeHexagonDAGToDAGISelPass(PassRegistry & Registry)195 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
196   CALL_ONCE_INITIALIZATION(initializePassOnce)
197 }
198 
199 
200 // Intrinsics that return a a predicate.
doesIntrinsicReturnPredicate(unsigned ID)201 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
202 {
203   switch (ID) {
204     default:
205       return 0;
206     case Intrinsic::hexagon_C2_cmpeq:
207     case Intrinsic::hexagon_C2_cmpgt:
208     case Intrinsic::hexagon_C2_cmpgtu:
209     case Intrinsic::hexagon_C2_cmpgtup:
210     case Intrinsic::hexagon_C2_cmpgtp:
211     case Intrinsic::hexagon_C2_cmpeqp:
212     case Intrinsic::hexagon_C2_bitsset:
213     case Intrinsic::hexagon_C2_bitsclr:
214     case Intrinsic::hexagon_C2_cmpeqi:
215     case Intrinsic::hexagon_C2_cmpgti:
216     case Intrinsic::hexagon_C2_cmpgtui:
217     case Intrinsic::hexagon_C2_cmpgei:
218     case Intrinsic::hexagon_C2_cmpgeui:
219     case Intrinsic::hexagon_C2_cmplt:
220     case Intrinsic::hexagon_C2_cmpltu:
221     case Intrinsic::hexagon_C2_bitsclri:
222     case Intrinsic::hexagon_C2_and:
223     case Intrinsic::hexagon_C2_or:
224     case Intrinsic::hexagon_C2_xor:
225     case Intrinsic::hexagon_C2_andn:
226     case Intrinsic::hexagon_C2_not:
227     case Intrinsic::hexagon_C2_orn:
228     case Intrinsic::hexagon_C2_pxfer_map:
229     case Intrinsic::hexagon_C2_any8:
230     case Intrinsic::hexagon_C2_all8:
231     case Intrinsic::hexagon_A2_vcmpbeq:
232     case Intrinsic::hexagon_A2_vcmpbgtu:
233     case Intrinsic::hexagon_A2_vcmpheq:
234     case Intrinsic::hexagon_A2_vcmphgt:
235     case Intrinsic::hexagon_A2_vcmphgtu:
236     case Intrinsic::hexagon_A2_vcmpweq:
237     case Intrinsic::hexagon_A2_vcmpwgt:
238     case Intrinsic::hexagon_A2_vcmpwgtu:
239     case Intrinsic::hexagon_C2_tfrrp:
240     case Intrinsic::hexagon_S2_tstbit_i:
241     case Intrinsic::hexagon_S2_tstbit_r:
242       return 1;
243   }
244 }
245 
SelectIndexedLoadSignExtend64(LoadSDNode * LD,unsigned Opcode,SDLoc dl)246 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
247                                                            unsigned Opcode,
248                                                            SDLoc dl) {
249   SDValue Chain = LD->getChain();
250   EVT LoadedVT = LD->getMemoryVT();
251   SDValue Base = LD->getBasePtr();
252   SDValue Offset = LD->getOffset();
253   SDNode *OffsetNode = Offset.getNode();
254   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
255 
256   const HexagonInstrInfo &TII = *HST->getInstrInfo();
257   if (TII.isValidAutoIncImm(LoadedVT, Val)) {
258     SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
259     SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
260                                               MVT::Other, Base, TargetConst,
261                                               Chain);
262     SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64,
263                                               SDValue(Result_1, 0));
264     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
265     MemOp[0] = LD->getMemOperand();
266     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
267     const SDValue Froms[] = { SDValue(LD, 0),
268                               SDValue(LD, 1),
269                               SDValue(LD, 2) };
270     const SDValue Tos[]   = { SDValue(Result_2, 0),
271                               SDValue(Result_1, 1),
272                               SDValue(Result_1, 2) };
273     ReplaceUses(Froms, Tos, 3);
274     return Result_2;
275   }
276 
277   SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
278   SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
279   SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::Other,
280                                             Base, TargetConst0, Chain);
281   SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64,
282                                             SDValue(Result_1, 0));
283   SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
284                                             Base, TargetConstVal,
285                                             SDValue(Result_1, 1));
286   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
287   MemOp[0] = LD->getMemOperand();
288   cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
289   const SDValue Froms[] = { SDValue(LD, 0),
290                             SDValue(LD, 1),
291                             SDValue(LD, 2) };
292   const SDValue Tos[]   = { SDValue(Result_2, 0),
293                             SDValue(Result_3, 0),
294                             SDValue(Result_1, 1) };
295   ReplaceUses(Froms, Tos, 3);
296   return Result_2;
297 }
298 
299 
SelectIndexedLoadZeroExtend64(LoadSDNode * LD,unsigned Opcode,SDLoc dl)300 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
301                                                            unsigned Opcode,
302                                                            SDLoc dl) {
303   SDValue Chain = LD->getChain();
304   EVT LoadedVT = LD->getMemoryVT();
305   SDValue Base = LD->getBasePtr();
306   SDValue Offset = LD->getOffset();
307   SDNode *OffsetNode = Offset.getNode();
308   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
309 
310   const HexagonInstrInfo &TII = *HST->getInstrInfo();
311   if (TII.isValidAutoIncImm(LoadedVT, Val)) {
312     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
313     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
314     SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
315                                               MVT::i32, MVT::Other, Base,
316                                               TargetConstVal, Chain);
317     SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A4_combineir, dl,
318                                               MVT::i64, MVT::Other,
319                                               TargetConst0,
320                                               SDValue(Result_1,0));
321     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
322     MemOp[0] = LD->getMemOperand();
323     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
324     const SDValue Froms[] = { SDValue(LD, 0),
325                               SDValue(LD, 1),
326                               SDValue(LD, 2) };
327     const SDValue Tos[]   = { SDValue(Result_2, 0),
328                               SDValue(Result_1, 1),
329                               SDValue(Result_1, 2) };
330     ReplaceUses(Froms, Tos, 3);
331     return Result_2;
332   }
333 
334   // Generate an indirect load.
335   SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
336   SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
337   SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
338                                             MVT::Other, Base, TargetConst0,
339                                             Chain);
340   SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A4_combineir, dl,
341                                             MVT::i64, MVT::Other,
342                                             TargetConst0,
343                                             SDValue(Result_1,0));
344   // Add offset to base.
345   SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
346                                             Base, TargetConstVal,
347                                             SDValue(Result_1, 1));
348   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
349   MemOp[0] = LD->getMemOperand();
350   cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
351   const SDValue Froms[] = { SDValue(LD, 0),
352                             SDValue(LD, 1),
353                             SDValue(LD, 2) };
354   const SDValue Tos[]   = { SDValue(Result_2, 0), // Load value.
355                             SDValue(Result_3, 0), // New address.
356                             SDValue(Result_1, 1) };
357   ReplaceUses(Froms, Tos, 3);
358   return Result_2;
359 }
360 
361 
SelectIndexedLoad(LoadSDNode * LD,SDLoc dl)362 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
363   SDValue Chain = LD->getChain();
364   SDValue Base = LD->getBasePtr();
365   SDValue Offset = LD->getOffset();
366   SDNode *OffsetNode = Offset.getNode();
367   // Get the constant value.
368   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
369   EVT LoadedVT = LD->getMemoryVT();
370   unsigned Opcode = 0;
371 
372   // Check for zero extended loads. Treat any-extend loads as zero extended
373   // loads.
374   ISD::LoadExtType ExtType = LD->getExtensionType();
375   bool IsZeroExt = (ExtType == ISD::ZEXTLOAD || ExtType == ISD::EXTLOAD);
376 
377   // Figure out the opcode.
378   const HexagonInstrInfo &TII = *HST->getInstrInfo();
379   if (LoadedVT == MVT::i64) {
380     if (TII.isValidAutoIncImm(LoadedVT, Val))
381       Opcode = Hexagon::L2_loadrd_pi;
382     else
383       Opcode = Hexagon::L2_loadrd_io;
384   } else if (LoadedVT == MVT::i32) {
385     if (TII.isValidAutoIncImm(LoadedVT, Val))
386       Opcode = Hexagon::L2_loadri_pi;
387     else
388       Opcode = Hexagon::L2_loadri_io;
389   } else if (LoadedVT == MVT::i16) {
390     if (TII.isValidAutoIncImm(LoadedVT, Val))
391       Opcode = IsZeroExt ? Hexagon::L2_loadruh_pi : Hexagon::L2_loadrh_pi;
392     else
393       Opcode = IsZeroExt ? Hexagon::L2_loadruh_io : Hexagon::L2_loadrh_io;
394   } else if (LoadedVT == MVT::i8) {
395     if (TII.isValidAutoIncImm(LoadedVT, Val))
396       Opcode = IsZeroExt ? Hexagon::L2_loadrub_pi : Hexagon::L2_loadrb_pi;
397     else
398       Opcode = IsZeroExt ? Hexagon::L2_loadrub_io : Hexagon::L2_loadrb_io;
399   } else
400     llvm_unreachable("unknown memory type");
401 
402   // For zero extended i64 loads, we need to add combine instructions.
403   if (LD->getValueType(0) == MVT::i64 && IsZeroExt)
404     return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
405   // Handle sign extended i64 loads.
406   if (LD->getValueType(0) == MVT::i64 && ExtType == ISD::SEXTLOAD)
407     return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
408 
409   if (TII.isValidAutoIncImm(LoadedVT, Val)) {
410     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
411     SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
412                                             LD->getValueType(0),
413                                             MVT::i32, MVT::Other, Base,
414                                             TargetConstVal, Chain);
415     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
416     MemOp[0] = LD->getMemOperand();
417     cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
418     const SDValue Froms[] = { SDValue(LD, 0),
419                               SDValue(LD, 1),
420                               SDValue(LD, 2)
421     };
422     const SDValue Tos[]   = { SDValue(Result, 0),
423                               SDValue(Result, 1),
424                               SDValue(Result, 2)
425     };
426     ReplaceUses(Froms, Tos, 3);
427     return Result;
428   } else {
429     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
430     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
431     SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
432                                               LD->getValueType(0),
433                                               MVT::Other, Base, TargetConst0,
434                                               Chain);
435     SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
436                                               Base, TargetConstVal,
437                                               SDValue(Result_1, 1));
438     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
439     MemOp[0] = LD->getMemOperand();
440     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
441     const SDValue Froms[] = { SDValue(LD, 0),
442                               SDValue(LD, 1),
443                               SDValue(LD, 2)
444     };
445     const SDValue Tos[]   = { SDValue(Result_1, 0),
446                               SDValue(Result_2, 0),
447                               SDValue(Result_1, 1)
448     };
449     ReplaceUses(Froms, Tos, 3);
450     return Result_1;
451   }
452 }
453 
454 
SelectLoad(SDNode * N)455 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
456   SDNode *result;
457   SDLoc dl(N);
458   LoadSDNode *LD = cast<LoadSDNode>(N);
459   ISD::MemIndexedMode AM = LD->getAddressingMode();
460 
461   // Handle indexed loads.
462   if (AM != ISD::UNINDEXED) {
463     result = SelectIndexedLoad(LD, dl);
464   } else {
465     result = SelectCode(LD);
466   }
467 
468   return result;
469 }
470 
471 
SelectIndexedStore(StoreSDNode * ST,SDLoc dl)472 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
473   SDValue Chain = ST->getChain();
474   SDValue Base = ST->getBasePtr();
475   SDValue Offset = ST->getOffset();
476   SDValue Value = ST->getValue();
477   SDNode *OffsetNode = Offset.getNode();
478   // Get the constant value.
479   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
480   EVT StoredVT = ST->getMemoryVT();
481   EVT ValueVT = Value.getValueType();
482 
483   // Offset value must be within representable range
484   // and must have correct alignment properties.
485   const HexagonInstrInfo &TII = *HST->getInstrInfo();
486   if (TII.isValidAutoIncImm(StoredVT, Val)) {
487     unsigned Opcode = 0;
488 
489     // Figure out the post inc version of opcode.
490     if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_pi;
491     else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_pi;
492     else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_pi;
493     else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_pi;
494     else llvm_unreachable("unknown memory type");
495 
496     if (ST->isTruncatingStore() && ValueVT.getSizeInBits() == 64) {
497       assert(StoredVT.getSizeInBits() < 64 && "Not a truncating store");
498       Value = CurDAG->getTargetExtractSubreg(Hexagon::subreg_loreg,
499                                              dl, MVT::i32, Value);
500     }
501     SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
502                      Chain};
503     // Build post increment store.
504     SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
505                                             MVT::Other, Ops);
506     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
507     MemOp[0] = ST->getMemOperand();
508     cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
509 
510     ReplaceUses(ST, Result);
511     ReplaceUses(SDValue(ST,1), SDValue(Result,1));
512     return Result;
513   }
514 
515   // Note: Order of operands matches the def of instruction:
516   // def S2_storerd_io
517   //   : STInst<(outs), (ins IntRegs:$base, imm:$offset, DoubleRegs:$src1), ...
518   // and it differs for POST_ST* for instance.
519   SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
520                     Chain};
521   unsigned Opcode = 0;
522 
523   // Figure out the opcode.
524   if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
525   else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
526   else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
527   else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
528   else llvm_unreachable("unknown memory type");
529 
530   // Build regular store.
531   SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
532   SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
533   // Build splitted incriment instruction.
534   SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
535                                             Base,
536                                             TargetConstVal,
537                                             SDValue(Result_1, 0));
538   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
539   MemOp[0] = ST->getMemOperand();
540   cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
541 
542   ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
543   ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
544   return Result_2;
545 }
546 
SelectStore(SDNode * N)547 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
548   SDLoc dl(N);
549   StoreSDNode *ST = cast<StoreSDNode>(N);
550   ISD::MemIndexedMode AM = ST->getAddressingMode();
551 
552   // Handle indexed stores.
553   if (AM != ISD::UNINDEXED) {
554     return SelectIndexedStore(ST, dl);
555   }
556 
557   return SelectCode(ST);
558 }
559 
SelectMul(SDNode * N)560 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
561   SDLoc dl(N);
562 
563   //
564   // %conv.i = sext i32 %tmp1 to i64
565   // %conv2.i = sext i32 %add to i64
566   // %mul.i = mul nsw i64 %conv2.i, %conv.i
567   //
568   //   --- match with the following ---
569   //
570   // %mul.i = mpy (%tmp1, %add)
571   //
572 
573   if (N->getValueType(0) == MVT::i64) {
574     // Shifting a i64 signed multiply.
575     SDValue MulOp0 = N->getOperand(0);
576     SDValue MulOp1 = N->getOperand(1);
577 
578     SDValue OP0;
579     SDValue OP1;
580 
581     // Handle sign_extend and sextload.
582     if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
583       SDValue Sext0 = MulOp0.getOperand(0);
584       if (Sext0.getNode()->getValueType(0) != MVT::i32) {
585         return SelectCode(N);
586       }
587 
588       OP0 = Sext0;
589     } else if (MulOp0.getOpcode() == ISD::LOAD) {
590       LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
591       if (LD->getMemoryVT() != MVT::i32 ||
592           LD->getExtensionType() != ISD::SEXTLOAD ||
593           LD->getAddressingMode() != ISD::UNINDEXED) {
594         return SelectCode(N);
595       }
596 
597       SDValue Chain = LD->getChain();
598       SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
599       OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
600                                             MVT::Other,
601                                             LD->getBasePtr(), TargetConst0,
602                                             Chain), 0);
603     } else {
604       return SelectCode(N);
605     }
606 
607     // Same goes for the second operand.
608     if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
609       SDValue Sext1 = MulOp1.getOperand(0);
610       if (Sext1.getNode()->getValueType(0) != MVT::i32) {
611         return SelectCode(N);
612       }
613 
614       OP1 = Sext1;
615     } else if (MulOp1.getOpcode() == ISD::LOAD) {
616       LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
617       if (LD->getMemoryVT() != MVT::i32 ||
618           LD->getExtensionType() != ISD::SEXTLOAD ||
619           LD->getAddressingMode() != ISD::UNINDEXED) {
620         return SelectCode(N);
621       }
622 
623       SDValue Chain = LD->getChain();
624       SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
625       OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
626                                             MVT::Other,
627                                             LD->getBasePtr(), TargetConst0,
628                                             Chain), 0);
629     } else {
630       return SelectCode(N);
631     }
632 
633     // Generate a mpy instruction.
634     SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl, MVT::i64,
635                                             OP0, OP1);
636     ReplaceUses(N, Result);
637     return Result;
638   }
639 
640   return SelectCode(N);
641 }
642 
SelectSHL(SDNode * N)643 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
644   SDLoc dl(N);
645   if (N->getValueType(0) == MVT::i32) {
646     SDValue Shl_0 = N->getOperand(0);
647     SDValue Shl_1 = N->getOperand(1);
648     // RHS is const.
649     if (Shl_1.getOpcode() == ISD::Constant) {
650       if (Shl_0.getOpcode() == ISD::MUL) {
651         SDValue Mul_0 = Shl_0.getOperand(0); // Val
652         SDValue Mul_1 = Shl_0.getOperand(1); // Const
653         // RHS of mul is const.
654         if (Mul_1.getOpcode() == ISD::Constant) {
655           int32_t ShlConst =
656             cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
657           int32_t MulConst =
658             cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
659           int32_t ValConst = MulConst << ShlConst;
660           SDValue Val = CurDAG->getTargetConstant(ValConst,
661                                                   MVT::i32);
662           if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
663             if (isInt<9>(CN->getSExtValue())) {
664               SDNode* Result =
665                 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
666                                        MVT::i32, Mul_0, Val);
667               ReplaceUses(N, Result);
668               return Result;
669             }
670 
671         }
672       } else if (Shl_0.getOpcode() == ISD::SUB) {
673         SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
674         SDValue Sub_1 = Shl_0.getOperand(1); // Val
675         if (Sub_0.getOpcode() == ISD::Constant) {
676           int32_t SubConst =
677             cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
678           if (SubConst == 0) {
679             if (Sub_1.getOpcode() == ISD::SHL) {
680               SDValue Shl2_0 = Sub_1.getOperand(0); // Val
681               SDValue Shl2_1 = Sub_1.getOperand(1); // Const
682               if (Shl2_1.getOpcode() == ISD::Constant) {
683                 int32_t ShlConst =
684                   cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
685                 int32_t Shl2Const =
686                   cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
687                 int32_t ValConst = 1 << (ShlConst+Shl2Const);
688                 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
689                 if (ConstantSDNode *CN =
690                     dyn_cast<ConstantSDNode>(Val.getNode()))
691                   if (isInt<9>(CN->getSExtValue())) {
692                     SDNode* Result =
693                       CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, MVT::i32,
694                                              Shl2_0, Val);
695                     ReplaceUses(N, Result);
696                     return Result;
697                   }
698               }
699             }
700           }
701         }
702       }
703     }
704   }
705   return SelectCode(N);
706 }
707 
708 
709 //
710 // If there is an zero_extend followed an intrinsic in DAG (this means - the
711 // result of the intrinsic is predicate); convert the zero_extend to
712 // transfer instruction.
713 //
714 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
715 // converted into a MUX as predicate registers defined as 1 bit in the
716 // compiler. Architecture defines them as 8-bit registers.
717 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
718 //
SelectZeroExtend(SDNode * N)719 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
720   SDLoc dl(N);
721 
722   SDValue Op0 = N->getOperand(0);
723   EVT OpVT = Op0.getValueType();
724   unsigned OpBW = OpVT.getSizeInBits();
725 
726   // Special handling for zero-extending a vector of booleans.
727   if (OpVT.isVector() && OpVT.getVectorElementType() == MVT::i1 && OpBW <= 64) {
728     SDNode *Mask = CurDAG->getMachineNode(Hexagon::C2_mask, dl, MVT::i64, Op0);
729     unsigned NE = OpVT.getVectorNumElements();
730     EVT ExVT = N->getValueType(0);
731     unsigned ES = ExVT.getVectorElementType().getSizeInBits();
732     uint64_t MV = 0, Bit = 1;
733     for (unsigned i = 0; i < NE; ++i) {
734       MV |= Bit;
735       Bit <<= ES;
736     }
737     SDValue Ones = CurDAG->getTargetConstant(MV, MVT::i64);
738     SDNode *OnesReg = CurDAG->getMachineNode(Hexagon::CONST64_Int_Real, dl,
739                                              MVT::i64, Ones);
740     if (ExVT.getSizeInBits() == 32) {
741       SDNode *And = CurDAG->getMachineNode(Hexagon::A2_andp, dl, MVT::i64,
742                                            SDValue(Mask,0), SDValue(OnesReg,0));
743       SDValue SubR = CurDAG->getTargetConstant(Hexagon::subreg_loreg, MVT::i32);
744       return CurDAG->getMachineNode(Hexagon::EXTRACT_SUBREG, dl, ExVT,
745                                     SDValue(And,0), SubR);
746     }
747     return CurDAG->getMachineNode(Hexagon::A2_andp, dl, ExVT,
748                                   SDValue(Mask,0), SDValue(OnesReg,0));
749   }
750 
751   SDNode *IsIntrinsic = N->getOperand(0).getNode();
752   if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
753     unsigned ID =
754       cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
755     if (doesIntrinsicReturnPredicate(ID)) {
756       // Now we need to differentiate target data types.
757       if (N->getValueType(0) == MVT::i64) {
758         // Convert the zero_extend to Rs = Pd followed by A2_combinew(0,Rs).
759         SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
760         SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
761                                                   MVT::i32,
762                                                   SDValue(IsIntrinsic, 0));
763         SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl,
764                                                   MVT::i32,
765                                                   TargetConst0);
766         SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
767                                                   MVT::i64, MVT::Other,
768                                                   SDValue(Result_2, 0),
769                                                   SDValue(Result_1, 0));
770         ReplaceUses(N, Result_3);
771         return Result_3;
772       }
773       if (N->getValueType(0) == MVT::i32) {
774         // Convert the zero_extend to Rs = Pd
775         SDNode* RsPd = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
776                                               MVT::i32,
777                                               SDValue(IsIntrinsic, 0));
778         ReplaceUses(N, RsPd);
779         return RsPd;
780       }
781       llvm_unreachable("Unexpected value type");
782     }
783   }
784   return SelectCode(N);
785 }
786 
787 //
788 // Checking for intrinsics circular load/store, and bitreverse load/store
789 // instrisics in order to select the correct lowered operation.
790 //
SelectIntrinsicWChain(SDNode * N)791 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWChain(SDNode *N) {
792   unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
793   if (IntNo == Intrinsic::hexagon_circ_ldd  ||
794       IntNo == Intrinsic::hexagon_circ_ldw  ||
795       IntNo == Intrinsic::hexagon_circ_lduh ||
796       IntNo == Intrinsic::hexagon_circ_ldh  ||
797       IntNo == Intrinsic::hexagon_circ_ldub ||
798       IntNo == Intrinsic::hexagon_circ_ldb) {
799     SDLoc dl(N);
800     SDValue Chain = N->getOperand(0);
801     SDValue Base = N->getOperand(2);
802     SDValue Load = N->getOperand(3);
803     SDValue ModifierExpr = N->getOperand(4);
804     SDValue Offset = N->getOperand(5);
805 
806     // We need to add the rerurn type for the load.  This intrinsic has
807     // two return types, one for the load and one for the post-increment.
808     // Only the *_ld instructions push the extra return type, and bump the
809     // result node operand number correspondingly.
810     std::vector<EVT> ResTys;
811     unsigned opc;
812     unsigned memsize, align;
813     MVT MvtSize = MVT::i32;
814 
815     if (IntNo == Intrinsic::hexagon_circ_ldd) {
816       ResTys.push_back(MVT::i32);
817       ResTys.push_back(MVT::i64);
818       opc = Hexagon::L2_loadrd_pci_pseudo;
819       memsize = 8;
820       align = 8;
821     } else if (IntNo == Intrinsic::hexagon_circ_ldw) {
822       ResTys.push_back(MVT::i32);
823       ResTys.push_back(MVT::i32);
824       opc = Hexagon::L2_loadri_pci_pseudo;
825       memsize = 4;
826       align = 4;
827     } else if (IntNo == Intrinsic::hexagon_circ_ldh) {
828       ResTys.push_back(MVT::i32);
829       ResTys.push_back(MVT::i32);
830       opc = Hexagon::L2_loadrh_pci_pseudo;
831       memsize = 2;
832       align = 2;
833       MvtSize = MVT::i16;
834     } else if (IntNo == Intrinsic::hexagon_circ_lduh) {
835       ResTys.push_back(MVT::i32);
836       ResTys.push_back(MVT::i32);
837       opc = Hexagon::L2_loadruh_pci_pseudo;
838       memsize = 2;
839       align = 2;
840       MvtSize = MVT::i16;
841     } else if (IntNo == Intrinsic::hexagon_circ_ldb) {
842       ResTys.push_back(MVT::i32);
843       ResTys.push_back(MVT::i32);
844       opc = Hexagon::L2_loadrb_pci_pseudo;
845       memsize = 1;
846       align = 1;
847       MvtSize = MVT::i8;
848     } else if (IntNo == Intrinsic::hexagon_circ_ldub) {
849       ResTys.push_back(MVT::i32);
850       ResTys.push_back(MVT::i32);
851       opc = Hexagon::L2_loadrub_pci_pseudo;
852       memsize = 1;
853       align = 1;
854       MvtSize = MVT::i8;
855     } else
856       llvm_unreachable("no opc");
857 
858     ResTys.push_back(MVT::Other);
859 
860     // Copy over the arguments, which are the same mostly.
861     SmallVector<SDValue, 5> Ops;
862     Ops.push_back(Base);
863     Ops.push_back(Load);
864     Ops.push_back(ModifierExpr);
865     int32_t Val = cast<ConstantSDNode>(Offset.getNode())->getSExtValue();
866     Ops.push_back(CurDAG->getTargetConstant(Val, MVT::i32));
867     Ops.push_back(Chain);
868     SDNode* Result = CurDAG->getMachineNode(opc, dl, ResTys, Ops);
869 
870     SDValue ST;
871     MachineMemOperand *Mem =
872       MF->getMachineMemOperand(MachinePointerInfo(),
873                                MachineMemOperand::MOStore, memsize, align);
874     if (MvtSize != MVT::i32)
875       ST = CurDAG->getTruncStore(Chain, dl, SDValue(Result, 1), Load,
876                                  MvtSize, Mem);
877     else
878       ST = CurDAG->getStore(Chain, dl, SDValue(Result, 1), Load, Mem);
879 
880     SDNode* Store = SelectStore(ST.getNode());
881 
882     const SDValue Froms[] = { SDValue(N, 0),
883                               SDValue(N, 1) };
884     const SDValue Tos[]   = { SDValue(Result, 0),
885                               SDValue(Store, 0) };
886     ReplaceUses(Froms, Tos, 2);
887     return Result;
888   }
889 
890   if (IntNo == Intrinsic::hexagon_brev_ldd  ||
891       IntNo == Intrinsic::hexagon_brev_ldw  ||
892       IntNo == Intrinsic::hexagon_brev_ldh  ||
893       IntNo == Intrinsic::hexagon_brev_lduh ||
894       IntNo == Intrinsic::hexagon_brev_ldb  ||
895       IntNo == Intrinsic::hexagon_brev_ldub) {
896     SDLoc dl(N);
897     SDValue Chain = N->getOperand(0);
898     SDValue Base = N->getOperand(2);
899     SDValue Load = N->getOperand(3);
900     SDValue ModifierExpr = N->getOperand(4);
901 
902     // We need to add the rerurn type for the load.  This intrinsic has
903     // two return types, one for the load and one for the post-increment.
904     std::vector<EVT> ResTys;
905     unsigned opc;
906     unsigned memsize, align;
907     MVT MvtSize = MVT::i32;
908 
909     if (IntNo == Intrinsic::hexagon_brev_ldd) {
910       ResTys.push_back(MVT::i32);
911       ResTys.push_back(MVT::i64);
912       opc = Hexagon::L2_loadrd_pbr_pseudo;
913       memsize = 8;
914       align = 8;
915     } else if (IntNo == Intrinsic::hexagon_brev_ldw) {
916       ResTys.push_back(MVT::i32);
917       ResTys.push_back(MVT::i32);
918       opc = Hexagon::L2_loadri_pbr_pseudo;
919       memsize = 4;
920       align = 4;
921     } else if (IntNo == Intrinsic::hexagon_brev_ldh) {
922       ResTys.push_back(MVT::i32);
923       ResTys.push_back(MVT::i32);
924       opc = Hexagon::L2_loadrh_pbr_pseudo;
925       memsize = 2;
926       align = 2;
927       MvtSize = MVT::i16;
928     } else if (IntNo == Intrinsic::hexagon_brev_lduh) {
929       ResTys.push_back(MVT::i32);
930       ResTys.push_back(MVT::i32);
931       opc = Hexagon::L2_loadruh_pbr_pseudo;
932       memsize = 2;
933       align = 2;
934       MvtSize = MVT::i16;
935     } else if (IntNo == Intrinsic::hexagon_brev_ldb) {
936       ResTys.push_back(MVT::i32);
937       ResTys.push_back(MVT::i32);
938       opc = Hexagon::L2_loadrb_pbr_pseudo;
939       memsize = 1;
940       align = 1;
941       MvtSize = MVT::i8;
942     } else if (IntNo == Intrinsic::hexagon_brev_ldub) {
943       ResTys.push_back(MVT::i32);
944       ResTys.push_back(MVT::i32);
945       opc = Hexagon::L2_loadrub_pbr_pseudo;
946       memsize = 1;
947       align = 1;
948       MvtSize = MVT::i8;
949     } else
950       llvm_unreachable("no opc");
951 
952     ResTys.push_back(MVT::Other);
953 
954     // Copy over the arguments, which are the same mostly.
955     SmallVector<SDValue, 4> Ops;
956     Ops.push_back(Base);
957     Ops.push_back(Load);
958     Ops.push_back(ModifierExpr);
959     Ops.push_back(Chain);
960     SDNode* Result = CurDAG->getMachineNode(opc, dl, ResTys, Ops);
961     SDValue ST;
962     MachineMemOperand *Mem =
963       MF->getMachineMemOperand(MachinePointerInfo(),
964                                MachineMemOperand::MOStore, memsize, align);
965     if (MvtSize != MVT::i32)
966       ST = CurDAG->getTruncStore(Chain, dl, SDValue(Result, 1), Load,
967                                  MvtSize, Mem);
968     else
969       ST = CurDAG->getStore(Chain, dl, SDValue(Result, 1), Load, Mem);
970 
971     SDNode* Store = SelectStore(ST.getNode());
972 
973     const SDValue Froms[] = { SDValue(N, 0),
974                               SDValue(N, 1) };
975     const SDValue Tos[]   = { SDValue(Result, 0),
976                               SDValue(Store, 0) };
977     ReplaceUses(Froms, Tos, 2);
978     return Result;
979   }
980 
981   return SelectCode(N);
982 }
983 
984 //
985 // Checking for intrinsics which have predicate registers as operand(s)
986 // and lowering to the actual intrinsic.
987 //
SelectIntrinsicWOChain(SDNode * N)988 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
989   unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
990   unsigned Bits;
991   switch (IID) {
992   case Intrinsic::hexagon_S2_vsplatrb:
993     Bits = 8;
994     break;
995   case Intrinsic::hexagon_S2_vsplatrh:
996     Bits = 16;
997     break;
998   default:
999     return SelectCode(N);
1000   }
1001 
1002   SDValue const &V = N->getOperand(1);
1003   SDValue U;
1004   if (isValueExtension(V, Bits, U)) {
1005     SDValue R = CurDAG->getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
1006       N->getOperand(0), U);
1007     return SelectCode(R.getNode());
1008   }
1009   return SelectCode(N);
1010 }
1011 
1012 //
1013 // Map floating point constant values.
1014 //
SelectConstantFP(SDNode * N)1015 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1016   SDLoc dl(N);
1017   ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1018   APFloat APF = CN->getValueAPF();
1019   if (N->getValueType(0) == MVT::f32) {
1020     return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1021               CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1022   }
1023   else if (N->getValueType(0) == MVT::f64) {
1024     return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1025               CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1026   }
1027 
1028   return SelectCode(N);
1029 }
1030 
1031 //
1032 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1033 //
SelectConstant(SDNode * N)1034 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1035   SDLoc dl(N);
1036   if (N->getValueType(0) == MVT::i1) {
1037     SDNode* Result = 0;
1038     int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1039     if (Val == -1) {
1040       Result = CurDAG->getMachineNode(Hexagon::TFR_PdTrue, dl, MVT::i1);
1041     } else if (Val == 0) {
1042       Result = CurDAG->getMachineNode(Hexagon::TFR_PdFalse, dl, MVT::i1);
1043     }
1044     if (Result) {
1045       ReplaceUses(N, Result);
1046       return Result;
1047     }
1048   }
1049 
1050   return SelectCode(N);
1051 }
1052 
1053 
1054 //
1055 // Map add followed by a asr -> asr +=.
1056 //
SelectAdd(SDNode * N)1057 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1058   SDLoc dl(N);
1059   if (N->getValueType(0) != MVT::i32) {
1060     return SelectCode(N);
1061   }
1062   // Identify nodes of the form: add(asr(...)).
1063   SDNode* Src1 = N->getOperand(0).getNode();
1064   if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1065       || Src1->getValueType(0) != MVT::i32) {
1066     return SelectCode(N);
1067   }
1068 
1069   // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1070   // Rd and Rd' are assigned to the same register
1071   SDNode* Result = CurDAG->getMachineNode(Hexagon::S2_asr_r_r_acc, dl, MVT::i32,
1072                                           N->getOperand(1),
1073                                           Src1->getOperand(0),
1074                                           Src1->getOperand(1));
1075   ReplaceUses(N, Result);
1076 
1077   return Result;
1078 }
1079 
1080 //
1081 // Map the following, where possible.
1082 // AND/FABS -> clrbit
1083 // OR -> setbit
1084 // XOR/FNEG ->toggle_bit.
1085 //
SelectBitOp(SDNode * N)1086 SDNode *HexagonDAGToDAGISel::SelectBitOp(SDNode *N) {
1087   SDLoc dl(N);
1088   EVT ValueVT = N->getValueType(0);
1089 
1090   // We handle only 32 and 64-bit bit ops.
1091   if (!(ValueVT == MVT::i32 || ValueVT == MVT::i64 ||
1092         ValueVT == MVT::f32 || ValueVT == MVT::f64))
1093     return SelectCode(N);
1094 
1095   // We handly only fabs and fneg for V5.
1096   unsigned Opc = N->getOpcode();
1097   if ((Opc == ISD::FABS || Opc == ISD::FNEG) && !HST->hasV5TOps())
1098     return SelectCode(N);
1099 
1100   int64_t Val = 0;
1101   if (Opc != ISD::FABS && Opc != ISD::FNEG) {
1102     if (N->getOperand(1).getOpcode() == ISD::Constant)
1103       Val = cast<ConstantSDNode>((N)->getOperand(1))->getSExtValue();
1104     else
1105      return SelectCode(N);
1106   }
1107 
1108   if (Opc == ISD::AND) {
1109     if (((ValueVT == MVT::i32) &&
1110                   (!((Val & 0x80000000) || (Val & 0x7fffffff)))) ||
1111         ((ValueVT == MVT::i64) &&
1112                   (!((Val & 0x8000000000000000) || (Val & 0x7fffffff)))))
1113       // If it's simple AND, do the normal op.
1114       return SelectCode(N);
1115     else
1116       Val = ~Val;
1117   }
1118 
1119   // If OR or AND is being fed by shl, srl and, sra don't do this change,
1120   // because Hexagon provide |= &= on shl, srl, and sra.
1121   // Traverse the DAG to see if there is shl, srl and sra.
1122   if (Opc == ISD::OR || Opc == ISD::AND) {
1123     switch (N->getOperand(0)->getOpcode()) {
1124       default: break;
1125       case ISD::SRA:
1126       case ISD::SRL:
1127       case ISD::SHL:
1128         return SelectCode(N);
1129     }
1130   }
1131 
1132   // Make sure it's power of 2.
1133   unsigned bitpos = 0;
1134   if (Opc != ISD::FABS && Opc != ISD::FNEG) {
1135     if (((ValueVT == MVT::i32) && !isPowerOf2_32(Val)) ||
1136         ((ValueVT == MVT::i64) && !isPowerOf2_64(Val)))
1137       return SelectCode(N);
1138 
1139     // Get the bit position.
1140     bitpos = countTrailingZeros(uint64_t(Val));
1141   } else {
1142     // For fabs and fneg, it's always the 31st bit.
1143     bitpos = 31;
1144   }
1145 
1146   unsigned BitOpc = 0;
1147   // Set the right opcode for bitwise operations.
1148   switch(Opc) {
1149     default: llvm_unreachable("Only bit-wise/abs/neg operations are allowed.");
1150     case ISD::AND:
1151     case ISD::FABS:
1152       BitOpc = Hexagon::S2_clrbit_i;
1153       break;
1154     case ISD::OR:
1155       BitOpc = Hexagon::S2_setbit_i;
1156       break;
1157     case ISD::XOR:
1158     case ISD::FNEG:
1159       BitOpc = Hexagon::S2_togglebit_i;
1160       break;
1161   }
1162 
1163   SDNode *Result;
1164   // Get the right SDVal for the opcode.
1165   SDValue SDVal = CurDAG->getTargetConstant(bitpos, MVT::i32);
1166 
1167   if (ValueVT == MVT::i32 || ValueVT == MVT::f32) {
1168     Result = CurDAG->getMachineNode(BitOpc, dl, ValueVT,
1169                                     N->getOperand(0), SDVal);
1170   } else {
1171     // 64-bit gymnastic to use REG_SEQUENCE. But it's worth it.
1172     EVT SubValueVT;
1173     if (ValueVT == MVT::i64)
1174       SubValueVT = MVT::i32;
1175     else
1176       SubValueVT = MVT::f32;
1177 
1178     SDNode *Reg = N->getOperand(0).getNode();
1179     SDValue RegClass = CurDAG->getTargetConstant(Hexagon::DoubleRegsRegClassID,
1180                                                  MVT::i64);
1181 
1182     SDValue SubregHiIdx = CurDAG->getTargetConstant(Hexagon::subreg_hireg,
1183                                                     MVT::i32);
1184     SDValue SubregLoIdx = CurDAG->getTargetConstant(Hexagon::subreg_loreg,
1185                                                     MVT::i32);
1186 
1187     SDValue SubregHI = CurDAG->getTargetExtractSubreg(Hexagon::subreg_hireg, dl,
1188                                                     MVT::i32, SDValue(Reg, 0));
1189 
1190     SDValue SubregLO = CurDAG->getTargetExtractSubreg(Hexagon::subreg_loreg, dl,
1191                                                     MVT::i32, SDValue(Reg, 0));
1192 
1193     // Clear/set/toggle hi or lo registers depending on the bit position.
1194     if (SubValueVT != MVT::f32 && bitpos < 32) {
1195       SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT,
1196                                                SubregLO, SDVal);
1197       const SDValue Ops[] = { RegClass, SubregHI, SubregHiIdx,
1198                               SDValue(Result0, 0), SubregLoIdx };
1199       Result = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
1200                                       dl, ValueVT, Ops);
1201     } else {
1202       if (Opc != ISD::FABS && Opc != ISD::FNEG)
1203         SDVal = CurDAG->getTargetConstant(bitpos-32, MVT::i32);
1204       SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT,
1205                                                SubregHI, SDVal);
1206       const SDValue Ops[] = { RegClass, SDValue(Result0, 0), SubregHiIdx,
1207                               SubregLO, SubregLoIdx };
1208       Result = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
1209                                       dl, ValueVT, Ops);
1210     }
1211   }
1212 
1213   ReplaceUses(N, Result);
1214   return Result;
1215 }
1216 
1217 
SelectFrameIndex(SDNode * N)1218 SDNode *HexagonDAGToDAGISel::SelectFrameIndex(SDNode *N) {
1219   int FX = cast<FrameIndexSDNode>(N)->getIndex();
1220   SDValue FI = CurDAG->getTargetFrameIndex(FX, MVT::i32);
1221   SDValue Zero = CurDAG->getTargetConstant(0, MVT::i32);
1222   SDLoc DL(N);
1223 
1224   SDNode *R = CurDAG->getMachineNode(Hexagon::TFR_FI, DL, MVT::i32, FI, Zero);
1225 
1226   if (N->getHasDebugValue())
1227     CurDAG->TransferDbgValues(SDValue(N, 0), SDValue(R, 0));
1228   return R;
1229 }
1230 
1231 
Select(SDNode * N)1232 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1233   if (N->isMachineOpcode()) {
1234     N->setNodeId(-1);
1235     return nullptr;   // Already selected.
1236   }
1237 
1238   switch (N->getOpcode()) {
1239   case ISD::Constant:
1240     return SelectConstant(N);
1241 
1242   case ISD::ConstantFP:
1243     return SelectConstantFP(N);
1244 
1245   case ISD::FrameIndex:
1246     return SelectFrameIndex(N);
1247 
1248   case ISD::ADD:
1249     return SelectAdd(N);
1250 
1251   case ISD::SHL:
1252     return SelectSHL(N);
1253 
1254   case ISD::LOAD:
1255     return SelectLoad(N);
1256 
1257   case ISD::STORE:
1258     return SelectStore(N);
1259 
1260   case ISD::MUL:
1261     return SelectMul(N);
1262 
1263   case ISD::AND:
1264   case ISD::OR:
1265   case ISD::XOR:
1266   case ISD::FABS:
1267   case ISD::FNEG:
1268     return SelectBitOp(N);
1269 
1270   case ISD::ZERO_EXTEND:
1271     return SelectZeroExtend(N);
1272 
1273   case ISD::INTRINSIC_W_CHAIN:
1274     return SelectIntrinsicWChain(N);
1275 
1276   case ISD::INTRINSIC_WO_CHAIN:
1277     return SelectIntrinsicWOChain(N);
1278   }
1279 
1280   return SelectCode(N);
1281 }
1282 
1283 
1284 bool HexagonDAGToDAGISel::
SelectInlineAsmMemoryOperand(const SDValue & Op,unsigned ConstraintID,std::vector<SDValue> & OutOps)1285 SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
1286                              std::vector<SDValue> &OutOps) {
1287   SDValue Inp = Op, Res;
1288 
1289   switch (ConstraintID) {
1290   default:
1291     return true;
1292   case InlineAsm::Constraint_i:
1293   case InlineAsm::Constraint_o: // Offsetable.
1294   case InlineAsm::Constraint_v: // Not offsetable.
1295   case InlineAsm::Constraint_m: // Memory.
1296     if (SelectAddrFI(Inp, Res))
1297       OutOps.push_back(Res);
1298     else
1299       OutOps.push_back(Inp);
1300     break;
1301   }
1302 
1303   OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
1304   return false;
1305 }
1306 
PreprocessISelDAG()1307 void HexagonDAGToDAGISel::PreprocessISelDAG() {
1308   SelectionDAG &DAG = *CurDAG;
1309   std::vector<SDNode*> Nodes;
1310   for (auto I = DAG.allnodes_begin(), E = DAG.allnodes_end(); I != E; ++I)
1311     Nodes.push_back(I);
1312 
1313   // Simplify: (or (select c x 0) z)  ->  (select c (or x z) z)
1314   //           (or (select c 0 y) z)  ->  (select c z (or y z))
1315   // This may not be the right thing for all targets, so do it here.
1316   for (auto I: Nodes) {
1317     if (I->getOpcode() != ISD::OR)
1318       continue;
1319 
1320     auto IsZero = [] (const SDValue &V) -> bool {
1321       if (ConstantSDNode *SC = dyn_cast<ConstantSDNode>(V.getNode()))
1322         return SC->isNullValue();
1323       return false;
1324     };
1325     auto IsSelect0 = [IsZero] (const SDValue &Op) -> bool {
1326       if (Op.getOpcode() != ISD::SELECT)
1327         return false;
1328       return IsZero(Op.getOperand(1))  || IsZero(Op.getOperand(2));
1329     };
1330 
1331     SDValue N0 = I->getOperand(0), N1 = I->getOperand(1);
1332     EVT VT = I->getValueType(0);
1333     bool SelN0 = IsSelect0(N0);
1334     SDValue SOp = SelN0 ? N0 : N1;
1335     SDValue VOp = SelN0 ? N1 : N0;
1336 
1337     if (SOp.getOpcode() == ISD::SELECT && SOp.getNode()->hasOneUse()) {
1338       SDValue SC = SOp.getOperand(0);
1339       SDValue SX = SOp.getOperand(1);
1340       SDValue SY = SOp.getOperand(2);
1341       SDLoc DLS = SOp;
1342       if (IsZero(SY)) {
1343         SDValue NewOr = DAG.getNode(ISD::OR, DLS, VT, SX, VOp);
1344         SDValue NewSel = DAG.getNode(ISD::SELECT, DLS, VT, SC, NewOr, VOp);
1345         DAG.ReplaceAllUsesWith(I, NewSel.getNode());
1346       } else if (IsZero(SX)) {
1347         SDValue NewOr = DAG.getNode(ISD::OR, DLS, VT, SY, VOp);
1348         SDValue NewSel = DAG.getNode(ISD::SELECT, DLS, VT, SC, VOp, NewOr);
1349         DAG.ReplaceAllUsesWith(I, NewSel.getNode());
1350       }
1351     }
1352   }
1353 }
1354 
1355 
SelectAddrFI(SDValue & N,SDValue & R)1356 bool HexagonDAGToDAGISel::SelectAddrFI(SDValue& N, SDValue &R) {
1357   if (N.getOpcode() != ISD::FrameIndex)
1358     return false;
1359   FrameIndexSDNode *FX = cast<FrameIndexSDNode>(N);
1360   R = CurDAG->getTargetFrameIndex(FX->getIndex(), MVT::i32);
1361   return true;
1362 }
1363 
SelectAddrGA(SDValue & N,SDValue & R)1364 inline bool HexagonDAGToDAGISel::SelectAddrGA(SDValue &N, SDValue &R) {
1365   return SelectGlobalAddress(N, R, false);
1366 }
1367 
SelectAddrGP(SDValue & N,SDValue & R)1368 inline bool HexagonDAGToDAGISel::SelectAddrGP(SDValue &N, SDValue &R) {
1369   return SelectGlobalAddress(N, R, true);
1370 }
1371 
SelectGlobalAddress(SDValue & N,SDValue & R,bool UseGP)1372 bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R,
1373                                               bool UseGP) {
1374   switch (N.getOpcode()) {
1375   case ISD::ADD: {
1376     SDValue N0 = N.getOperand(0);
1377     SDValue N1 = N.getOperand(1);
1378     unsigned GAOpc = N0.getOpcode();
1379     if (UseGP && GAOpc != HexagonISD::CONST32_GP)
1380       return false;
1381     if (!UseGP && GAOpc != HexagonISD::CONST32)
1382       return false;
1383     if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1)) {
1384       SDValue Addr = N0.getOperand(0);
1385       if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Addr)) {
1386         if (GA->getOpcode() == ISD::TargetGlobalAddress) {
1387           uint64_t NewOff = GA->getOffset() + (uint64_t)Const->getSExtValue();
1388           R = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(Const),
1389                                              N.getValueType(), NewOff);
1390           return true;
1391         }
1392       }
1393     }
1394     break;
1395   }
1396   case HexagonISD::CONST32:
1397     // The operand(0) of CONST32 is TargetGlobalAddress, which is what we
1398     // want in the instruction.
1399     if (!UseGP)
1400       R = N.getOperand(0);
1401     return !UseGP;
1402   case HexagonISD::CONST32_GP:
1403     if (UseGP)
1404       R = N.getOperand(0);
1405     return UseGP;
1406   default:
1407     return false;
1408   }
1409 
1410   return false;
1411 }
1412 
isValueExtension(const SDValue & Val,unsigned FromBits,SDValue & Src)1413 bool HexagonDAGToDAGISel::isValueExtension(const SDValue &Val,
1414       unsigned FromBits, SDValue &Src) {
1415   unsigned Opc = Val.getOpcode();
1416   switch (Opc) {
1417   case ISD::SIGN_EXTEND:
1418   case ISD::ZERO_EXTEND:
1419   case ISD::ANY_EXTEND: {
1420     SDValue const &Op0 = Val.getOperand(0);
1421     EVT T = Op0.getValueType();
1422     if (T.isInteger() && T.getSizeInBits() == FromBits) {
1423       Src = Op0;
1424       return true;
1425     }
1426     break;
1427   }
1428   case ISD::SIGN_EXTEND_INREG:
1429   case ISD::AssertSext:
1430   case ISD::AssertZext:
1431     if (Val.getOperand(0).getValueType().isInteger()) {
1432       VTSDNode *T = cast<VTSDNode>(Val.getOperand(1));
1433       if (T->getVT().getSizeInBits() == FromBits) {
1434         Src = Val.getOperand(0);
1435         return true;
1436       }
1437     }
1438     break;
1439   case ISD::AND: {
1440     // Check if this is an AND with "FromBits" of lower bits set to 1.
1441     uint64_t FromMask = (1 << FromBits) - 1;
1442     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
1443       if (C->getZExtValue() == FromMask) {
1444         Src = Val.getOperand(1);
1445         return true;
1446       }
1447     }
1448     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
1449       if (C->getZExtValue() == FromMask) {
1450         Src = Val.getOperand(0);
1451         return true;
1452       }
1453     }
1454     break;
1455   }
1456   case ISD::OR:
1457   case ISD::XOR: {
1458     // OR/XOR with the lower "FromBits" bits set to 0.
1459     uint64_t FromMask = (1 << FromBits) - 1;
1460     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
1461       if ((C->getZExtValue() & FromMask) == 0) {
1462         Src = Val.getOperand(1);
1463         return true;
1464       }
1465     }
1466     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
1467       if ((C->getZExtValue() & FromMask) == 0) {
1468         Src = Val.getOperand(0);
1469         return true;
1470       }
1471     }
1472   }
1473   default:
1474     break;
1475   }
1476   return false;
1477 }
1478