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