LLVM  mainline
HexagonISelDAGToDAG.cpp
Go to the documentation of this file.
00001 //===-- HexagonISelDAGToDAG.cpp - A dag to dag inst selector for Hexagon --===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines an instruction selector for the Hexagon target.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "Hexagon.h"
00015 #include "HexagonISelLowering.h"
00016 #include "HexagonTargetMachine.h"
00017 #include "llvm/ADT/DenseMap.h"
00018 #include "llvm/CodeGen/SelectionDAGISel.h"
00019 #include "llvm/IR/Intrinsics.h"
00020 #include "llvm/Support/CommandLine.h"
00021 #include "llvm/Support/Compiler.h"
00022 #include "llvm/Support/Debug.h"
00023 using namespace llvm;
00024 
00025 #define DEBUG_TYPE "hexagon-isel"
00026 
00027 static
00028 cl::opt<unsigned>
00029 MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders",
00030   cl::Hidden, cl::init(2),
00031   cl::desc("Maximum number of uses of a global address such that we still us a"
00032            "constant extended instruction"));
00033 
00034 //===----------------------------------------------------------------------===//
00035 // Instruction Selector Implementation
00036 //===----------------------------------------------------------------------===//
00037 
00038 namespace llvm {
00039   void initializeHexagonDAGToDAGISelPass(PassRegistry&);
00040 }
00041 
00042 //===--------------------------------------------------------------------===//
00043 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
00044 /// instructions for SelectionDAG operations.
00045 ///
00046 namespace {
00047 class HexagonDAGToDAGISel : public SelectionDAGISel {
00048   const HexagonTargetMachine& HTM;
00049   const HexagonSubtarget *HST;
00050 public:
00051   explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm,
00052                                CodeGenOpt::Level OptLevel)
00053       : SelectionDAGISel(tm, OptLevel), HTM(tm) {
00054     initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
00055   }
00056 
00057   bool runOnMachineFunction(MachineFunction &MF) override {
00058     // Reset the subtarget each time through.
00059     HST = &MF.getSubtarget<HexagonSubtarget>();
00060     SelectionDAGISel::runOnMachineFunction(MF);
00061     return true;
00062   }
00063 
00064   virtual void PreprocessISelDAG() override;
00065 
00066   SDNode *Select(SDNode *N) override;
00067 
00068   // Complex Pattern Selectors.
00069   inline bool SelectAddrGA(SDValue &N, SDValue &R);
00070   inline bool SelectAddrGP(SDValue &N, SDValue &R);
00071   bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP);
00072   bool SelectAddrFI(SDValue &N, SDValue &R);
00073 
00074   const char *getPassName() const override {
00075     return "Hexagon DAG->DAG Pattern Instruction Selection";
00076   }
00077 
00078   SDNode *SelectFrameIndex(SDNode *N);
00079   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
00080   /// inline asm expressions.
00081   bool SelectInlineAsmMemoryOperand(const SDValue &Op,
00082                                     unsigned ConstraintID,
00083                                     std::vector<SDValue> &OutOps) override;
00084   SDNode *SelectLoad(SDNode *N);
00085   SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl);
00086   SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl);
00087   SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
00088                                         SDLoc dl);
00089   SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
00090                                         SDLoc dl);
00091   SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl);
00092   SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl);
00093   SDNode *SelectStore(SDNode *N);
00094   SDNode *SelectSHL(SDNode *N);
00095   SDNode *SelectMul(SDNode *N);
00096   SDNode *SelectZeroExtend(SDNode *N);
00097   SDNode *SelectIntrinsicWChain(SDNode *N);
00098   SDNode *SelectIntrinsicWOChain(SDNode *N);
00099   SDNode *SelectConstant(SDNode *N);
00100   SDNode *SelectConstantFP(SDNode *N);
00101   SDNode *SelectAdd(SDNode *N);
00102   SDNode *SelectBitOp(SDNode *N);
00103 
00104   // XformMskToBitPosU5Imm - Returns the bit position which
00105   // the single bit 32 bit mask represents.
00106   // Used in Clr and Set bit immediate memops.
00107   SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
00108     int32_t bitPos;
00109     bitPos = Log2_32(Imm);
00110     assert(bitPos >= 0 && bitPos < 32 &&
00111            "Constant out of range for 32 BitPos Memops");
00112     return CurDAG->getTargetConstant(bitPos, MVT::i32);
00113   }
00114 
00115   // XformMskToBitPosU4Imm - Returns the bit position which the single-bit
00116   // 16 bit mask represents. Used in Clr and Set bit immediate memops.
00117   SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
00118     return XformMskToBitPosU5Imm(Imm);
00119   }
00120 
00121   // XformMskToBitPosU3Imm - Returns the bit position which the single-bit
00122   // 8 bit mask represents. Used in Clr and Set bit immediate memops.
00123   SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
00124     return XformMskToBitPosU5Imm(Imm);
00125   }
00126 
00127   // Return true if there is exactly one bit set in V, i.e., if V is one of the
00128   // following integers: 2^0, 2^1, ..., 2^31.
00129   bool ImmIsSingleBit(uint32_t v) const {
00130     return isPowerOf2_32(v);
00131   }
00132 
00133   // XformM5ToU5Imm - Return a target constant with the specified value, of
00134   // type i32 where the negative literal is transformed into a positive literal
00135   // for use in -= memops.
00136   inline SDValue XformM5ToU5Imm(signed Imm) {
00137      assert( (Imm >= -31 && Imm <= -1)  && "Constant out of range for Memops");
00138      return CurDAG->getTargetConstant( - Imm, MVT::i32);
00139   }
00140 
00141   // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
00142   // [1..128], used in cmpb.gtu instructions.
00143   inline SDValue XformU7ToU7M1Imm(signed Imm) {
00144     assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
00145     return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
00146   }
00147 
00148   // XformS8ToS8M1Imm - Return a target constant decremented by 1.
00149   inline SDValue XformSToSM1Imm(signed Imm) {
00150     return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
00151   }
00152 
00153   // XformU8ToU8M1Imm - Return a target constant decremented by 1.
00154   inline SDValue XformUToUM1Imm(unsigned Imm) {
00155     assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
00156     return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
00157   }
00158 
00159   // XformSToSM2Imm - Return a target constant decremented by 2.
00160   inline SDValue XformSToSM2Imm(unsigned Imm) {
00161     return CurDAG->getTargetConstant(Imm - 2, MVT::i32);
00162   }
00163 
00164   // XformSToSM3Imm - Return a target constant decremented by 3.
00165   inline SDValue XformSToSM3Imm(unsigned Imm) {
00166     return CurDAG->getTargetConstant(Imm - 3, MVT::i32);
00167   }
00168 
00169   // Include the pieces autogenerated from the target description.
00170   #include "HexagonGenDAGISel.inc"
00171 
00172 private:
00173   bool isValueExtension(const SDValue &Val, unsigned FromBits, SDValue &Src);
00174 }; // end HexagonDAGToDAGISel
00175 }  // end anonymous namespace
00176 
00177 
00178 /// createHexagonISelDag - This pass converts a legalized DAG into a
00179 /// Hexagon-specific DAG, ready for instruction scheduling.
00180 ///
00181 namespace llvm {
00182 FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM,
00183                                    CodeGenOpt::Level OptLevel) {
00184   return new HexagonDAGToDAGISel(TM, OptLevel);
00185 }
00186 }
00187 
00188 static void initializePassOnce(PassRegistry &Registry) {
00189   const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
00190   PassInfo *PI = new PassInfo(Name, "hexagon-isel",
00191                               &SelectionDAGISel::ID, nullptr, false, false);
00192   Registry.registerPass(*PI, true);
00193 }
00194 
00195 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
00196   CALL_ONCE_INITIALIZATION(initializePassOnce)
00197 }
00198 
00199 
00200 // Intrinsics that return a a predicate.
00201 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
00202 {
00203   switch (ID) {
00204     default:
00205       return 0;
00206     case Intrinsic::hexagon_C2_cmpeq:
00207     case Intrinsic::hexagon_C2_cmpgt:
00208     case Intrinsic::hexagon_C2_cmpgtu:
00209     case Intrinsic::hexagon_C2_cmpgtup:
00210     case Intrinsic::hexagon_C2_cmpgtp:
00211     case Intrinsic::hexagon_C2_cmpeqp:
00212     case Intrinsic::hexagon_C2_bitsset:
00213     case Intrinsic::hexagon_C2_bitsclr:
00214     case Intrinsic::hexagon_C2_cmpeqi:
00215     case Intrinsic::hexagon_C2_cmpgti:
00216     case Intrinsic::hexagon_C2_cmpgtui:
00217     case Intrinsic::hexagon_C2_cmpgei:
00218     case Intrinsic::hexagon_C2_cmpgeui:
00219     case Intrinsic::hexagon_C2_cmplt:
00220     case Intrinsic::hexagon_C2_cmpltu:
00221     case Intrinsic::hexagon_C2_bitsclri:
00222     case Intrinsic::hexagon_C2_and:
00223     case Intrinsic::hexagon_C2_or:
00224     case Intrinsic::hexagon_C2_xor:
00225     case Intrinsic::hexagon_C2_andn:
00226     case Intrinsic::hexagon_C2_not:
00227     case Intrinsic::hexagon_C2_orn:
00228     case Intrinsic::hexagon_C2_pxfer_map:
00229     case Intrinsic::hexagon_C2_any8:
00230     case Intrinsic::hexagon_C2_all8:
00231     case Intrinsic::hexagon_A2_vcmpbeq:
00232     case Intrinsic::hexagon_A2_vcmpbgtu:
00233     case Intrinsic::hexagon_A2_vcmpheq:
00234     case Intrinsic::hexagon_A2_vcmphgt:
00235     case Intrinsic::hexagon_A2_vcmphgtu:
00236     case Intrinsic::hexagon_A2_vcmpweq:
00237     case Intrinsic::hexagon_A2_vcmpwgt:
00238     case Intrinsic::hexagon_A2_vcmpwgtu:
00239     case Intrinsic::hexagon_C2_tfrrp:
00240     case Intrinsic::hexagon_S2_tstbit_i:
00241     case Intrinsic::hexagon_S2_tstbit_r:
00242       return 1;
00243   }
00244 }
00245 
00246 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
00247                                                            unsigned Opcode,
00248                                                            SDLoc dl) {
00249   SDValue Chain = LD->getChain();
00250   EVT LoadedVT = LD->getMemoryVT();
00251   SDValue Base = LD->getBasePtr();
00252   SDValue Offset = LD->getOffset();
00253   SDNode *OffsetNode = Offset.getNode();
00254   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
00255 
00256   const HexagonInstrInfo &TII = *HST->getInstrInfo();
00257   if (TII.isValidAutoIncImm(LoadedVT, Val)) {
00258     SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
00259     SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
00260                                               MVT::Other, Base, TargetConst,
00261                                               Chain);
00262     SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64,
00263                                               SDValue(Result_1, 0));
00264     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00265     MemOp[0] = LD->getMemOperand();
00266     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00267     const SDValue Froms[] = { SDValue(LD, 0),
00268                               SDValue(LD, 1),
00269                               SDValue(LD, 2) };
00270     const SDValue Tos[]   = { SDValue(Result_2, 0),
00271                               SDValue(Result_1, 1),
00272                               SDValue(Result_1, 2) };
00273     ReplaceUses(Froms, Tos, 3);
00274     return Result_2;
00275   }
00276 
00277   SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00278   SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00279   SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::Other,
00280                                             Base, TargetConst0, Chain);
00281   SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64,
00282                                             SDValue(Result_1, 0));
00283   SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
00284                                             Base, TargetConstVal,
00285                                             SDValue(Result_1, 1));
00286   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00287   MemOp[0] = LD->getMemOperand();
00288   cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00289   const SDValue Froms[] = { SDValue(LD, 0),
00290                             SDValue(LD, 1),
00291                             SDValue(LD, 2) };
00292   const SDValue Tos[]   = { SDValue(Result_2, 0),
00293                             SDValue(Result_3, 0),
00294                             SDValue(Result_1, 1) };
00295   ReplaceUses(Froms, Tos, 3);
00296   return Result_2;
00297 }
00298 
00299 
00300 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
00301                                                            unsigned Opcode,
00302                                                            SDLoc dl) {
00303   SDValue Chain = LD->getChain();
00304   EVT LoadedVT = LD->getMemoryVT();
00305   SDValue Base = LD->getBasePtr();
00306   SDValue Offset = LD->getOffset();
00307   SDNode *OffsetNode = Offset.getNode();
00308   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
00309 
00310   const HexagonInstrInfo &TII = *HST->getInstrInfo();
00311   if (TII.isValidAutoIncImm(LoadedVT, Val)) {
00312     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00313     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00314     SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
00315                                               MVT::i32, MVT::Other, Base,
00316                                               TargetConstVal, Chain);
00317     SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A4_combineir, dl,
00318                                               MVT::i64, MVT::Other,
00319                                               TargetConst0,
00320                                               SDValue(Result_1,0));
00321     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00322     MemOp[0] = LD->getMemOperand();
00323     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00324     const SDValue Froms[] = { SDValue(LD, 0),
00325                               SDValue(LD, 1),
00326                               SDValue(LD, 2) };
00327     const SDValue Tos[]   = { SDValue(Result_2, 0),
00328                               SDValue(Result_1, 1),
00329                               SDValue(Result_1, 2) };
00330     ReplaceUses(Froms, Tos, 3);
00331     return Result_2;
00332   }
00333 
00334   // Generate an indirect load.
00335   SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00336   SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00337   SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
00338                                             MVT::Other, Base, TargetConst0,
00339                                             Chain);
00340   SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A4_combineir, dl,
00341                                             MVT::i64, MVT::Other,
00342                                             TargetConst0,
00343                                             SDValue(Result_1,0));
00344   // Add offset to base.
00345   SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
00346                                             Base, TargetConstVal,
00347                                             SDValue(Result_1, 1));
00348   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00349   MemOp[0] = LD->getMemOperand();
00350   cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00351   const SDValue Froms[] = { SDValue(LD, 0),
00352                             SDValue(LD, 1),
00353                             SDValue(LD, 2) };
00354   const SDValue Tos[]   = { SDValue(Result_2, 0), // Load value.
00355                             SDValue(Result_3, 0), // New address.
00356                             SDValue(Result_1, 1) };
00357   ReplaceUses(Froms, Tos, 3);
00358   return Result_2;
00359 }
00360 
00361 
00362 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
00363   SDValue Chain = LD->getChain();
00364   SDValue Base = LD->getBasePtr();
00365   SDValue Offset = LD->getOffset();
00366   SDNode *OffsetNode = Offset.getNode();
00367   // Get the constant value.
00368   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
00369   EVT LoadedVT = LD->getMemoryVT();
00370   unsigned Opcode = 0;
00371 
00372   // Check for zero extended loads. Treat any-extend loads as zero extended
00373   // loads.
00374   ISD::LoadExtType ExtType = LD->getExtensionType();
00375   bool IsZeroExt = (ExtType == ISD::ZEXTLOAD || ExtType == ISD::EXTLOAD);
00376 
00377   // Figure out the opcode.
00378   const HexagonInstrInfo &TII = *HST->getInstrInfo();
00379   if (LoadedVT == MVT::i64) {
00380     if (TII.isValidAutoIncImm(LoadedVT, Val))
00381       Opcode = Hexagon::L2_loadrd_pi;
00382     else
00383       Opcode = Hexagon::L2_loadrd_io;
00384   } else if (LoadedVT == MVT::i32) {
00385     if (TII.isValidAutoIncImm(LoadedVT, Val))
00386       Opcode = Hexagon::L2_loadri_pi;
00387     else
00388       Opcode = Hexagon::L2_loadri_io;
00389   } else if (LoadedVT == MVT::i16) {
00390     if (TII.isValidAutoIncImm(LoadedVT, Val))
00391       Opcode = IsZeroExt ? Hexagon::L2_loadruh_pi : Hexagon::L2_loadrh_pi;
00392     else
00393       Opcode = IsZeroExt ? Hexagon::L2_loadruh_io : Hexagon::L2_loadrh_io;
00394   } else if (LoadedVT == MVT::i8) {
00395     if (TII.isValidAutoIncImm(LoadedVT, Val))
00396       Opcode = IsZeroExt ? Hexagon::L2_loadrub_pi : Hexagon::L2_loadrb_pi;
00397     else
00398       Opcode = IsZeroExt ? Hexagon::L2_loadrub_io : Hexagon::L2_loadrb_io;
00399   } else
00400     llvm_unreachable("unknown memory type");
00401 
00402   // For zero extended i64 loads, we need to add combine instructions.
00403   if (LD->getValueType(0) == MVT::i64 && IsZeroExt)
00404     return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
00405   // Handle sign extended i64 loads.
00406   if (LD->getValueType(0) == MVT::i64 && ExtType == ISD::SEXTLOAD)
00407     return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
00408 
00409   if (TII.isValidAutoIncImm(LoadedVT, Val)) {
00410     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00411     SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
00412                                             LD->getValueType(0),
00413                                             MVT::i32, MVT::Other, Base,
00414                                             TargetConstVal, Chain);
00415     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00416     MemOp[0] = LD->getMemOperand();
00417     cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
00418     const SDValue Froms[] = { SDValue(LD, 0),
00419                               SDValue(LD, 1),
00420                               SDValue(LD, 2)
00421     };
00422     const SDValue Tos[]   = { SDValue(Result, 0),
00423                               SDValue(Result, 1),
00424                               SDValue(Result, 2)
00425     };
00426     ReplaceUses(Froms, Tos, 3);
00427     return Result;
00428   } else {
00429     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00430     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00431     SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
00432                                               LD->getValueType(0),
00433                                               MVT::Other, Base, TargetConst0,
00434                                               Chain);
00435     SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
00436                                               Base, TargetConstVal,
00437                                               SDValue(Result_1, 1));
00438     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00439     MemOp[0] = LD->getMemOperand();
00440     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00441     const SDValue Froms[] = { SDValue(LD, 0),
00442                               SDValue(LD, 1),
00443                               SDValue(LD, 2)
00444     };
00445     const SDValue Tos[]   = { SDValue(Result_1, 0),
00446                               SDValue(Result_2, 0),
00447                               SDValue(Result_1, 1)
00448     };
00449     ReplaceUses(Froms, Tos, 3);
00450     return Result_1;
00451   }
00452 }
00453 
00454 
00455 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
00456   SDNode *result;
00457   SDLoc dl(N);
00458   LoadSDNode *LD = cast<LoadSDNode>(N);
00459   ISD::MemIndexedMode AM = LD->getAddressingMode();
00460 
00461   // Handle indexed loads.
00462   if (AM != ISD::UNINDEXED) {
00463     result = SelectIndexedLoad(LD, dl);
00464   } else {
00465     result = SelectCode(LD);
00466   }
00467 
00468   return result;
00469 }
00470 
00471 
00472 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
00473   SDValue Chain = ST->getChain();
00474   SDValue Base = ST->getBasePtr();
00475   SDValue Offset = ST->getOffset();
00476   SDValue Value = ST->getValue();
00477   SDNode *OffsetNode = Offset.getNode();
00478   // Get the constant value.
00479   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
00480   EVT StoredVT = ST->getMemoryVT();
00481   EVT ValueVT = Value.getValueType();
00482 
00483   // Offset value must be within representable range
00484   // and must have correct alignment properties.
00485   const HexagonInstrInfo &TII = *HST->getInstrInfo();
00486   if (TII.isValidAutoIncImm(StoredVT, Val)) {
00487     unsigned Opcode = 0;
00488 
00489     // Figure out the post inc version of opcode.
00490     if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_pi;
00491     else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_pi;
00492     else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_pi;
00493     else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_pi;
00494     else llvm_unreachable("unknown memory type");
00495 
00496     if (ST->isTruncatingStore() && ValueVT.getSizeInBits() == 64) {
00497       assert(StoredVT.getSizeInBits() < 64 && "Not a truncating store");
00498       Value = CurDAG->getTargetExtractSubreg(Hexagon::subreg_loreg,
00499                                              dl, MVT::i32, Value);
00500     }
00501     SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
00502                      Chain};
00503     // Build post increment store.
00504     SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
00505                                             MVT::Other, Ops);
00506     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00507     MemOp[0] = ST->getMemOperand();
00508     cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
00509 
00510     ReplaceUses(ST, Result);
00511     ReplaceUses(SDValue(ST,1), SDValue(Result,1));
00512     return Result;
00513   }
00514 
00515   // Note: Order of operands matches the def of instruction:
00516   // def S2_storerd_io
00517   //   : STInst<(outs), (ins IntRegs:$base, imm:$offset, DoubleRegs:$src1), ...
00518   // and it differs for POST_ST* for instance.
00519   SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
00520                     Chain};
00521   unsigned Opcode = 0;
00522 
00523   // Figure out the opcode.
00524   if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
00525   else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
00526   else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
00527   else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
00528   else llvm_unreachable("unknown memory type");
00529 
00530   // Build regular store.
00531   SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00532   SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
00533   // Build splitted incriment instruction.
00534   SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::A2_addi, dl, MVT::i32,
00535                                             Base,
00536                                             TargetConstVal,
00537                                             SDValue(Result_1, 0));
00538   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00539   MemOp[0] = ST->getMemOperand();
00540   cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00541 
00542   ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
00543   ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
00544   return Result_2;
00545 }
00546 
00547 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
00548   SDLoc dl(N);
00549   StoreSDNode *ST = cast<StoreSDNode>(N);
00550   ISD::MemIndexedMode AM = ST->getAddressingMode();
00551 
00552   // Handle indexed stores.
00553   if (AM != ISD::UNINDEXED) {
00554     return SelectIndexedStore(ST, dl);
00555   }
00556 
00557   return SelectCode(ST);
00558 }
00559 
00560 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
00561   SDLoc dl(N);
00562 
00563   //
00564   // %conv.i = sext i32 %tmp1 to i64
00565   // %conv2.i = sext i32 %add to i64
00566   // %mul.i = mul nsw i64 %conv2.i, %conv.i
00567   //
00568   //   --- match with the following ---
00569   //
00570   // %mul.i = mpy (%tmp1, %add)
00571   //
00572 
00573   if (N->getValueType(0) == MVT::i64) {
00574     // Shifting a i64 signed multiply.
00575     SDValue MulOp0 = N->getOperand(0);
00576     SDValue MulOp1 = N->getOperand(1);
00577 
00578     SDValue OP0;
00579     SDValue OP1;
00580 
00581     // Handle sign_extend and sextload.
00582     if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
00583       SDValue Sext0 = MulOp0.getOperand(0);
00584       if (Sext0.getNode()->getValueType(0) != MVT::i32) {
00585         return SelectCode(N);
00586       }
00587 
00588       OP0 = Sext0;
00589     } else if (MulOp0.getOpcode() == ISD::LOAD) {
00590       LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
00591       if (LD->getMemoryVT() != MVT::i32 ||
00592           LD->getExtensionType() != ISD::SEXTLOAD ||
00593           LD->getAddressingMode() != ISD::UNINDEXED) {
00594         return SelectCode(N);
00595       }
00596 
00597       SDValue Chain = LD->getChain();
00598       SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00599       OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
00600                                             MVT::Other,
00601                                             LD->getBasePtr(), TargetConst0,
00602                                             Chain), 0);
00603     } else {
00604       return SelectCode(N);
00605     }
00606 
00607     // Same goes for the second operand.
00608     if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
00609       SDValue Sext1 = MulOp1.getOperand(0);
00610       if (Sext1.getNode()->getValueType(0) != MVT::i32) {
00611         return SelectCode(N);
00612       }
00613 
00614       OP1 = Sext1;
00615     } else if (MulOp1.getOpcode() == ISD::LOAD) {
00616       LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
00617       if (LD->getMemoryVT() != MVT::i32 ||
00618           LD->getExtensionType() != ISD::SEXTLOAD ||
00619           LD->getAddressingMode() != ISD::UNINDEXED) {
00620         return SelectCode(N);
00621       }
00622 
00623       SDValue Chain = LD->getChain();
00624       SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00625       OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
00626                                             MVT::Other,
00627                                             LD->getBasePtr(), TargetConst0,
00628                                             Chain), 0);
00629     } else {
00630       return SelectCode(N);
00631     }
00632 
00633     // Generate a mpy instruction.
00634     SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl, MVT::i64,
00635                                             OP0, OP1);
00636     ReplaceUses(N, Result);
00637     return Result;
00638   }
00639 
00640   return SelectCode(N);
00641 }
00642 
00643 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
00644   SDLoc dl(N);
00645   if (N->getValueType(0) == MVT::i32) {
00646     SDValue Shl_0 = N->getOperand(0);
00647     SDValue Shl_1 = N->getOperand(1);
00648     // RHS is const.
00649     if (Shl_1.getOpcode() == ISD::Constant) {
00650       if (Shl_0.getOpcode() == ISD::MUL) {
00651         SDValue Mul_0 = Shl_0.getOperand(0); // Val
00652         SDValue Mul_1 = Shl_0.getOperand(1); // Const
00653         // RHS of mul is const.
00654         if (Mul_1.getOpcode() == ISD::Constant) {
00655           int32_t ShlConst =
00656             cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
00657           int32_t MulConst =
00658             cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
00659           int32_t ValConst = MulConst << ShlConst;
00660           SDValue Val = CurDAG->getTargetConstant(ValConst,
00661                                                   MVT::i32);
00662           if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
00663             if (isInt<9>(CN->getSExtValue())) {
00664               SDNode* Result =
00665                 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
00666                                        MVT::i32, Mul_0, Val);
00667               ReplaceUses(N, Result);
00668               return Result;
00669             }
00670 
00671         }
00672       } else if (Shl_0.getOpcode() == ISD::SUB) {
00673         SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
00674         SDValue Sub_1 = Shl_0.getOperand(1); // Val
00675         if (Sub_0.getOpcode() == ISD::Constant) {
00676           int32_t SubConst =
00677             cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
00678           if (SubConst == 0) {
00679             if (Sub_1.getOpcode() == ISD::SHL) {
00680               SDValue Shl2_0 = Sub_1.getOperand(0); // Val
00681               SDValue Shl2_1 = Sub_1.getOperand(1); // Const
00682               if (Shl2_1.getOpcode() == ISD::Constant) {
00683                 int32_t ShlConst =
00684                   cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
00685                 int32_t Shl2Const =
00686                   cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
00687                 int32_t ValConst = 1 << (ShlConst+Shl2Const);
00688                 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
00689                 if (ConstantSDNode *CN =
00690                     dyn_cast<ConstantSDNode>(Val.getNode()))
00691                   if (isInt<9>(CN->getSExtValue())) {
00692                     SDNode* Result =
00693                       CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, MVT::i32,
00694                                              Shl2_0, Val);
00695                     ReplaceUses(N, Result);
00696                     return Result;
00697                   }
00698               }
00699             }
00700           }
00701         }
00702       }
00703     }
00704   }
00705   return SelectCode(N);
00706 }
00707 
00708 
00709 //
00710 // If there is an zero_extend followed an intrinsic in DAG (this means - the
00711 // result of the intrinsic is predicate); convert the zero_extend to
00712 // transfer instruction.
00713 //
00714 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
00715 // converted into a MUX as predicate registers defined as 1 bit in the
00716 // compiler. Architecture defines them as 8-bit registers.
00717 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
00718 //
00719 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
00720   SDLoc dl(N);
00721 
00722   SDValue Op0 = N->getOperand(0);
00723   EVT OpVT = Op0.getValueType();
00724   unsigned OpBW = OpVT.getSizeInBits();
00725 
00726   // Special handling for zero-extending a vector of booleans.
00727   if (OpVT.isVector() && OpVT.getVectorElementType() == MVT::i1 && OpBW <= 64) {
00728     SDNode *Mask = CurDAG->getMachineNode(Hexagon::C2_mask, dl, MVT::i64, Op0);
00729     unsigned NE = OpVT.getVectorNumElements();
00730     EVT ExVT = N->getValueType(0);
00731     unsigned ES = ExVT.getVectorElementType().getSizeInBits();
00732     uint64_t MV = 0, Bit = 1;
00733     for (unsigned i = 0; i < NE; ++i) {
00734       MV |= Bit;
00735       Bit <<= ES;
00736     }
00737     SDValue Ones = CurDAG->getTargetConstant(MV, MVT::i64);
00738     SDNode *OnesReg = CurDAG->getMachineNode(Hexagon::CONST64_Int_Real, dl,
00739                                              MVT::i64, Ones);
00740     if (ExVT.getSizeInBits() == 32) {
00741       SDNode *And = CurDAG->getMachineNode(Hexagon::A2_andp, dl, MVT::i64,
00742                                            SDValue(Mask,0), SDValue(OnesReg,0));
00743       SDValue SubR = CurDAG->getTargetConstant(Hexagon::subreg_loreg, MVT::i32);
00744       return CurDAG->getMachineNode(Hexagon::EXTRACT_SUBREG, dl, ExVT,
00745                                     SDValue(And,0), SubR);
00746     }
00747     return CurDAG->getMachineNode(Hexagon::A2_andp, dl, ExVT,
00748                                   SDValue(Mask,0), SDValue(OnesReg,0));
00749   }
00750 
00751   SDNode *IsIntrinsic = N->getOperand(0).getNode();
00752   if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
00753     unsigned ID =
00754       cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
00755     if (doesIntrinsicReturnPredicate(ID)) {
00756       // Now we need to differentiate target data types.
00757       if (N->getValueType(0) == MVT::i64) {
00758         // Convert the zero_extend to Rs = Pd followed by A2_combinew(0,Rs).
00759         SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00760         SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
00761                                                   MVT::i32,
00762                                                   SDValue(IsIntrinsic, 0));
00763         SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl,
00764                                                   MVT::i32,
00765                                                   TargetConst0);
00766         SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
00767                                                   MVT::i64, MVT::Other,
00768                                                   SDValue(Result_2, 0),
00769                                                   SDValue(Result_1, 0));
00770         ReplaceUses(N, Result_3);
00771         return Result_3;
00772       }
00773       if (N->getValueType(0) == MVT::i32) {
00774         // Convert the zero_extend to Rs = Pd
00775         SDNode* RsPd = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
00776                                               MVT::i32,
00777                                               SDValue(IsIntrinsic, 0));
00778         ReplaceUses(N, RsPd);
00779         return RsPd;
00780       }
00781       llvm_unreachable("Unexpected value type");
00782     }
00783   }
00784   return SelectCode(N);
00785 }
00786 
00787 //
00788 // Checking for intrinsics circular load/store, and bitreverse load/store
00789 // instrisics in order to select the correct lowered operation.
00790 //
00791 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWChain(SDNode *N) {
00792   unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
00793   if (IntNo == Intrinsic::hexagon_circ_ldd  ||
00794       IntNo == Intrinsic::hexagon_circ_ldw  ||
00795       IntNo == Intrinsic::hexagon_circ_lduh ||
00796       IntNo == Intrinsic::hexagon_circ_ldh  ||
00797       IntNo == Intrinsic::hexagon_circ_ldub ||
00798       IntNo == Intrinsic::hexagon_circ_ldb) {
00799     SDLoc dl(N);
00800     SDValue Chain = N->getOperand(0);
00801     SDValue Base = N->getOperand(2);
00802     SDValue Load = N->getOperand(3);
00803     SDValue ModifierExpr = N->getOperand(4);
00804     SDValue Offset = N->getOperand(5);
00805 
00806     // We need to add the rerurn type for the load.  This intrinsic has
00807     // two return types, one for the load and one for the post-increment.
00808     // Only the *_ld instructions push the extra return type, and bump the
00809     // result node operand number correspondingly.
00810     std::vector<EVT> ResTys;
00811     unsigned opc;
00812     unsigned memsize, align;
00813     MVT MvtSize = MVT::i32;
00814 
00815     if (IntNo == Intrinsic::hexagon_circ_ldd) {
00816       ResTys.push_back(MVT::i32);
00817       ResTys.push_back(MVT::i64);
00818       opc = Hexagon::L2_loadrd_pci_pseudo;
00819       memsize = 8;
00820       align = 8;
00821     } else if (IntNo == Intrinsic::hexagon_circ_ldw) {
00822       ResTys.push_back(MVT::i32);
00823       ResTys.push_back(MVT::i32);
00824       opc = Hexagon::L2_loadri_pci_pseudo;
00825       memsize = 4;
00826       align = 4;
00827     } else if (IntNo == Intrinsic::hexagon_circ_ldh) {
00828       ResTys.push_back(MVT::i32);
00829       ResTys.push_back(MVT::i32);
00830       opc = Hexagon::L2_loadrh_pci_pseudo;
00831       memsize = 2;
00832       align = 2;
00833       MvtSize = MVT::i16;
00834     } else if (IntNo == Intrinsic::hexagon_circ_lduh) {
00835       ResTys.push_back(MVT::i32);
00836       ResTys.push_back(MVT::i32);
00837       opc = Hexagon::L2_loadruh_pci_pseudo;
00838       memsize = 2;
00839       align = 2;
00840       MvtSize = MVT::i16;
00841     } else if (IntNo == Intrinsic::hexagon_circ_ldb) {
00842       ResTys.push_back(MVT::i32);
00843       ResTys.push_back(MVT::i32);
00844       opc = Hexagon::L2_loadrb_pci_pseudo;
00845       memsize = 1;
00846       align = 1;
00847       MvtSize = MVT::i8;
00848     } else if (IntNo == Intrinsic::hexagon_circ_ldub) {
00849       ResTys.push_back(MVT::i32);
00850       ResTys.push_back(MVT::i32);
00851       opc = Hexagon::L2_loadrub_pci_pseudo;
00852       memsize = 1;
00853       align = 1;
00854       MvtSize = MVT::i8;
00855     } else
00856       llvm_unreachable("no opc");
00857 
00858     ResTys.push_back(MVT::Other);
00859 
00860     // Copy over the arguments, which are the same mostly.
00861     SmallVector<SDValue, 5> Ops;
00862     Ops.push_back(Base);
00863     Ops.push_back(Load);
00864     Ops.push_back(ModifierExpr);
00865     int32_t Val = cast<ConstantSDNode>(Offset.getNode())->getSExtValue();
00866     Ops.push_back(CurDAG->getTargetConstant(Val, MVT::i32));
00867     Ops.push_back(Chain);
00868     SDNode* Result = CurDAG->getMachineNode(opc, dl, ResTys, Ops);
00869 
00870     SDValue ST;
00871     MachineMemOperand *Mem =
00872       MF->getMachineMemOperand(MachinePointerInfo(),
00873                                MachineMemOperand::MOStore, memsize, align);
00874     if (MvtSize != MVT::i32)
00875       ST = CurDAG->getTruncStore(Chain, dl, SDValue(Result, 1), Load,
00876                                  MvtSize, Mem);
00877     else
00878       ST = CurDAG->getStore(Chain, dl, SDValue(Result, 1), Load, Mem);
00879 
00880     SDNode* Store = SelectStore(ST.getNode());
00881 
00882     const SDValue Froms[] = { SDValue(N, 0),
00883                               SDValue(N, 1) };
00884     const SDValue Tos[]   = { SDValue(Result, 0),
00885                               SDValue(Store, 0) };
00886     ReplaceUses(Froms, Tos, 2);
00887     return Result;
00888   }
00889 
00890   if (IntNo == Intrinsic::hexagon_brev_ldd  ||
00891       IntNo == Intrinsic::hexagon_brev_ldw  ||
00892       IntNo == Intrinsic::hexagon_brev_ldh  ||
00893       IntNo == Intrinsic::hexagon_brev_lduh ||
00894       IntNo == Intrinsic::hexagon_brev_ldb  ||
00895       IntNo == Intrinsic::hexagon_brev_ldub) {
00896     SDLoc dl(N);
00897     SDValue Chain = N->getOperand(0);
00898     SDValue Base = N->getOperand(2);
00899     SDValue Load = N->getOperand(3);
00900     SDValue ModifierExpr = N->getOperand(4);
00901 
00902     // We need to add the rerurn type for the load.  This intrinsic has
00903     // two return types, one for the load and one for the post-increment.
00904     std::vector<EVT> ResTys;
00905     unsigned opc;
00906     unsigned memsize, align;
00907     MVT MvtSize = MVT::i32;
00908 
00909     if (IntNo == Intrinsic::hexagon_brev_ldd) {
00910       ResTys.push_back(MVT::i32);
00911       ResTys.push_back(MVT::i64);
00912       opc = Hexagon::L2_loadrd_pbr_pseudo;
00913       memsize = 8;
00914       align = 8;
00915     } else if (IntNo == Intrinsic::hexagon_brev_ldw) {
00916       ResTys.push_back(MVT::i32);
00917       ResTys.push_back(MVT::i32);
00918       opc = Hexagon::L2_loadri_pbr_pseudo;
00919       memsize = 4;
00920       align = 4;
00921     } else if (IntNo == Intrinsic::hexagon_brev_ldh) {
00922       ResTys.push_back(MVT::i32);
00923       ResTys.push_back(MVT::i32);
00924       opc = Hexagon::L2_loadrh_pbr_pseudo;
00925       memsize = 2;
00926       align = 2;
00927       MvtSize = MVT::i16;
00928     } else if (IntNo == Intrinsic::hexagon_brev_lduh) {
00929       ResTys.push_back(MVT::i32);
00930       ResTys.push_back(MVT::i32);
00931       opc = Hexagon::L2_loadruh_pbr_pseudo;
00932       memsize = 2;
00933       align = 2;
00934       MvtSize = MVT::i16;
00935     } else if (IntNo == Intrinsic::hexagon_brev_ldb) {
00936       ResTys.push_back(MVT::i32);
00937       ResTys.push_back(MVT::i32);
00938       opc = Hexagon::L2_loadrb_pbr_pseudo;
00939       memsize = 1;
00940       align = 1;
00941       MvtSize = MVT::i8;
00942     } else if (IntNo == Intrinsic::hexagon_brev_ldub) {
00943       ResTys.push_back(MVT::i32);
00944       ResTys.push_back(MVT::i32);
00945       opc = Hexagon::L2_loadrub_pbr_pseudo;
00946       memsize = 1;
00947       align = 1;
00948       MvtSize = MVT::i8;
00949     } else
00950       llvm_unreachable("no opc");
00951 
00952     ResTys.push_back(MVT::Other);
00953 
00954     // Copy over the arguments, which are the same mostly.
00955     SmallVector<SDValue, 4> Ops;
00956     Ops.push_back(Base);
00957     Ops.push_back(Load);
00958     Ops.push_back(ModifierExpr);
00959     Ops.push_back(Chain);
00960     SDNode* Result = CurDAG->getMachineNode(opc, dl, ResTys, Ops);
00961     SDValue ST;
00962     MachineMemOperand *Mem =
00963       MF->getMachineMemOperand(MachinePointerInfo(),
00964                                MachineMemOperand::MOStore, memsize, align);
00965     if (MvtSize != MVT::i32)
00966       ST = CurDAG->getTruncStore(Chain, dl, SDValue(Result, 1), Load,
00967                                  MvtSize, Mem);
00968     else
00969       ST = CurDAG->getStore(Chain, dl, SDValue(Result, 1), Load, Mem);
00970 
00971     SDNode* Store = SelectStore(ST.getNode());
00972 
00973     const SDValue Froms[] = { SDValue(N, 0),
00974                               SDValue(N, 1) };
00975     const SDValue Tos[]   = { SDValue(Result, 0),
00976                               SDValue(Store, 0) };
00977     ReplaceUses(Froms, Tos, 2);
00978     return Result;
00979   }
00980 
00981   return SelectCode(N);
00982 }
00983 
00984 //
00985 // Checking for intrinsics which have predicate registers as operand(s)
00986 // and lowering to the actual intrinsic.
00987 //
00988 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
00989   unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
00990   unsigned Bits;
00991   switch (IID) {
00992   case Intrinsic::hexagon_S2_vsplatrb:
00993     Bits = 8;
00994     break;
00995   case Intrinsic::hexagon_S2_vsplatrh:
00996     Bits = 16;
00997     break;
00998   default:
00999     return SelectCode(N);
01000   }
01001 
01002   SDValue const &V = N->getOperand(1);
01003   SDValue U;
01004   if (isValueExtension(V, Bits, U)) {
01005     SDValue R = CurDAG->getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
01006       N->getOperand(0), U);
01007     return SelectCode(R.getNode());
01008   }
01009   return SelectCode(N);
01010 }
01011 
01012 //
01013 // Map floating point constant values.
01014 //
01015 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
01016   SDLoc dl(N);
01017   ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
01018   APFloat APF = CN->getValueAPF();
01019   if (N->getValueType(0) == MVT::f32) {
01020     return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
01021               CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
01022   }
01023   else if (N->getValueType(0) == MVT::f64) {
01024     return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
01025               CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
01026   }
01027 
01028   return SelectCode(N);
01029 }
01030 
01031 //
01032 // Map predicate true (encoded as -1 in LLVM) to a XOR.
01033 //
01034 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
01035   SDLoc dl(N);
01036   if (N->getValueType(0) == MVT::i1) {
01037     SDNode* Result = 0;
01038     int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
01039     if (Val == -1) {
01040       Result = CurDAG->getMachineNode(Hexagon::TFR_PdTrue, dl, MVT::i1);
01041     } else if (Val == 0) {
01042       Result = CurDAG->getMachineNode(Hexagon::TFR_PdFalse, dl, MVT::i1);
01043     }
01044     if (Result) {
01045       ReplaceUses(N, Result);
01046       return Result;
01047     }
01048   }
01049 
01050   return SelectCode(N);
01051 }
01052 
01053 
01054 //
01055 // Map add followed by a asr -> asr +=.
01056 //
01057 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
01058   SDLoc dl(N);
01059   if (N->getValueType(0) != MVT::i32) {
01060     return SelectCode(N);
01061   }
01062   // Identify nodes of the form: add(asr(...)).
01063   SDNode* Src1 = N->getOperand(0).getNode();
01064   if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
01065       || Src1->getValueType(0) != MVT::i32) {
01066     return SelectCode(N);
01067   }
01068 
01069   // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
01070   // Rd and Rd' are assigned to the same register
01071   SDNode* Result = CurDAG->getMachineNode(Hexagon::S2_asr_r_r_acc, dl, MVT::i32,
01072                                           N->getOperand(1),
01073                                           Src1->getOperand(0),
01074                                           Src1->getOperand(1));
01075   ReplaceUses(N, Result);
01076 
01077   return Result;
01078 }
01079 
01080 //
01081 // Map the following, where possible.
01082 // AND/FABS -> clrbit
01083 // OR -> setbit
01084 // XOR/FNEG ->toggle_bit.
01085 //
01086 SDNode *HexagonDAGToDAGISel::SelectBitOp(SDNode *N) {
01087   SDLoc dl(N);
01088   EVT ValueVT = N->getValueType(0);
01089 
01090   // We handle only 32 and 64-bit bit ops.
01091   if (!(ValueVT == MVT::i32 || ValueVT == MVT::i64 ||
01092         ValueVT == MVT::f32 || ValueVT == MVT::f64))
01093     return SelectCode(N);
01094 
01095   // We handly only fabs and fneg for V5.
01096   unsigned Opc = N->getOpcode();
01097   if ((Opc == ISD::FABS || Opc == ISD::FNEG) && !HST->hasV5TOps())
01098     return SelectCode(N);
01099 
01100   int64_t Val = 0;
01101   if (Opc != ISD::FABS && Opc != ISD::FNEG) {
01102     if (N->getOperand(1).getOpcode() == ISD::Constant)
01103       Val = cast<ConstantSDNode>((N)->getOperand(1))->getSExtValue();
01104     else
01105      return SelectCode(N);
01106   }
01107 
01108   if (Opc == ISD::AND) {
01109     if (((ValueVT == MVT::i32) &&
01110                   (!((Val & 0x80000000) || (Val & 0x7fffffff)))) ||
01111         ((ValueVT == MVT::i64) &&
01112                   (!((Val & 0x8000000000000000) || (Val & 0x7fffffff)))))
01113       // If it's simple AND, do the normal op.
01114       return SelectCode(N);
01115     else
01116       Val = ~Val;
01117   }
01118 
01119   // If OR or AND is being fed by shl, srl and, sra don't do this change,
01120   // because Hexagon provide |= &= on shl, srl, and sra.
01121   // Traverse the DAG to see if there is shl, srl and sra.
01122   if (Opc == ISD::OR || Opc == ISD::AND) {
01123     switch (N->getOperand(0)->getOpcode()) {
01124       default: break;
01125       case ISD::SRA:
01126       case ISD::SRL:
01127       case ISD::SHL:
01128         return SelectCode(N);
01129     }
01130   }
01131 
01132   // Make sure it's power of 2.
01133   unsigned bitpos = 0;
01134   if (Opc != ISD::FABS && Opc != ISD::FNEG) {
01135     if (((ValueVT == MVT::i32) && !isPowerOf2_32(Val)) ||
01136         ((ValueVT == MVT::i64) && !isPowerOf2_64(Val)))
01137       return SelectCode(N);
01138 
01139     // Get the bit position.
01140     bitpos = countTrailingZeros(uint64_t(Val));
01141   } else {
01142     // For fabs and fneg, it's always the 31st bit.
01143     bitpos = 31;
01144   }
01145 
01146   unsigned BitOpc = 0;
01147   // Set the right opcode for bitwise operations.
01148   switch(Opc) {
01149     default: llvm_unreachable("Only bit-wise/abs/neg operations are allowed.");
01150     case ISD::AND:
01151     case ISD::FABS:
01152       BitOpc = Hexagon::S2_clrbit_i;
01153       break;
01154     case ISD::OR:
01155       BitOpc = Hexagon::S2_setbit_i;
01156       break;
01157     case ISD::XOR:
01158     case ISD::FNEG:
01159       BitOpc = Hexagon::S2_togglebit_i;
01160       break;
01161   }
01162 
01163   SDNode *Result;
01164   // Get the right SDVal for the opcode.
01165   SDValue SDVal = CurDAG->getTargetConstant(bitpos, MVT::i32);
01166 
01167   if (ValueVT == MVT::i32 || ValueVT == MVT::f32) {
01168     Result = CurDAG->getMachineNode(BitOpc, dl, ValueVT,
01169                                     N->getOperand(0), SDVal);
01170   } else {
01171     // 64-bit gymnastic to use REG_SEQUENCE. But it's worth it.
01172     EVT SubValueVT;
01173     if (ValueVT == MVT::i64)
01174       SubValueVT = MVT::i32;
01175     else
01176       SubValueVT = MVT::f32;
01177 
01178     SDNode *Reg = N->getOperand(0).getNode();
01179     SDValue RegClass = CurDAG->getTargetConstant(Hexagon::DoubleRegsRegClassID,
01180                                                  MVT::i64);
01181 
01182     SDValue SubregHiIdx = CurDAG->getTargetConstant(Hexagon::subreg_hireg,
01183                                                     MVT::i32);
01184     SDValue SubregLoIdx = CurDAG->getTargetConstant(Hexagon::subreg_loreg,
01185                                                     MVT::i32);
01186 
01187     SDValue SubregHI = CurDAG->getTargetExtractSubreg(Hexagon::subreg_hireg, dl,
01188                                                     MVT::i32, SDValue(Reg, 0));
01189 
01190     SDValue SubregLO = CurDAG->getTargetExtractSubreg(Hexagon::subreg_loreg, dl,
01191                                                     MVT::i32, SDValue(Reg, 0));
01192 
01193     // Clear/set/toggle hi or lo registers depending on the bit position.
01194     if (SubValueVT != MVT::f32 && bitpos < 32) {
01195       SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT,
01196                                                SubregLO, SDVal);
01197       const SDValue Ops[] = { RegClass, SubregHI, SubregHiIdx,
01198                               SDValue(Result0, 0), SubregLoIdx };
01199       Result = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
01200                                       dl, ValueVT, Ops);
01201     } else {
01202       if (Opc != ISD::FABS && Opc != ISD::FNEG)
01203         SDVal = CurDAG->getTargetConstant(bitpos-32, MVT::i32);
01204       SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT,
01205                                                SubregHI, SDVal);
01206       const SDValue Ops[] = { RegClass, SDValue(Result0, 0), SubregHiIdx,
01207                               SubregLO, SubregLoIdx };
01208       Result = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
01209                                       dl, ValueVT, Ops);
01210     }
01211   }
01212 
01213   ReplaceUses(N, Result);
01214   return Result;
01215 }
01216 
01217 
01218 SDNode *HexagonDAGToDAGISel::SelectFrameIndex(SDNode *N) {
01219   int FX = cast<FrameIndexSDNode>(N)->getIndex();
01220   SDValue FI = CurDAG->getTargetFrameIndex(FX, MVT::i32);
01221   SDValue Zero = CurDAG->getTargetConstant(0, MVT::i32);
01222   SDLoc DL(N);
01223 
01224   SDNode *R = CurDAG->getMachineNode(Hexagon::TFR_FI, DL, MVT::i32, FI, Zero);
01225 
01226   if (N->getHasDebugValue())
01227     CurDAG->TransferDbgValues(SDValue(N, 0), SDValue(R, 0));
01228   return R;
01229 }
01230 
01231 
01232 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
01233   if (N->isMachineOpcode()) {
01234     N->setNodeId(-1);
01235     return nullptr;   // Already selected.
01236   }
01237 
01238   switch (N->getOpcode()) {
01239   case ISD::Constant:
01240     return SelectConstant(N);
01241 
01242   case ISD::ConstantFP:
01243     return SelectConstantFP(N);
01244 
01245   case ISD::FrameIndex:
01246     return SelectFrameIndex(N);
01247 
01248   case ISD::ADD:
01249     return SelectAdd(N);
01250 
01251   case ISD::SHL:
01252     return SelectSHL(N);
01253 
01254   case ISD::LOAD:
01255     return SelectLoad(N);
01256 
01257   case ISD::STORE:
01258     return SelectStore(N);
01259 
01260   case ISD::MUL:
01261     return SelectMul(N);
01262 
01263   case ISD::AND:
01264   case ISD::OR:
01265   case ISD::XOR:
01266   case ISD::FABS:
01267   case ISD::FNEG:
01268     return SelectBitOp(N);
01269 
01270   case ISD::ZERO_EXTEND:
01271     return SelectZeroExtend(N);
01272 
01273   case ISD::INTRINSIC_W_CHAIN:
01274     return SelectIntrinsicWChain(N);
01275 
01276   case ISD::INTRINSIC_WO_CHAIN:
01277     return SelectIntrinsicWOChain(N);
01278   }
01279 
01280   return SelectCode(N);
01281 }
01282 
01283 
01284 bool HexagonDAGToDAGISel::
01285 SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
01286                              std::vector<SDValue> &OutOps) {
01287   SDValue Inp = Op, Res;
01288 
01289   switch (ConstraintID) {
01290   default:
01291     return true;
01292   case InlineAsm::Constraint_i:
01293   case InlineAsm::Constraint_o: // Offsetable.
01294   case InlineAsm::Constraint_v: // Not offsetable.
01295   case InlineAsm::Constraint_m: // Memory.
01296     if (SelectAddrFI(Inp, Res))
01297       OutOps.push_back(Res);
01298     else
01299       OutOps.push_back(Inp);
01300     break;
01301   }
01302 
01303   OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
01304   return false;
01305 }
01306 
01307 void HexagonDAGToDAGISel::PreprocessISelDAG() {
01308   SelectionDAG &DAG = *CurDAG;
01309   std::vector<SDNode*> Nodes;
01310   for (auto I = DAG.allnodes_begin(), E = DAG.allnodes_end(); I != E; ++I)
01311     Nodes.push_back(I);
01312 
01313   // Simplify: (or (select c x 0) z)  ->  (select c (or x z) z)
01314   //           (or (select c 0 y) z)  ->  (select c z (or y z))
01315   // This may not be the right thing for all targets, so do it here.
01316   for (auto I: Nodes) {
01317     if (I->getOpcode() != ISD::OR)
01318       continue;
01319 
01320     auto IsZero = [] (const SDValue &V) -> bool {
01321       if (ConstantSDNode *SC = dyn_cast<ConstantSDNode>(V.getNode()))
01322         return SC->isNullValue();
01323       return false;
01324     };
01325     auto IsSelect0 = [IsZero] (const SDValue &Op) -> bool {
01326       if (Op.getOpcode() != ISD::SELECT)
01327         return false;
01328       return IsZero(Op.getOperand(1))  || IsZero(Op.getOperand(2));
01329     };
01330 
01331     SDValue N0 = I->getOperand(0), N1 = I->getOperand(1);
01332     EVT VT = I->getValueType(0);
01333     bool SelN0 = IsSelect0(N0);
01334     SDValue SOp = SelN0 ? N0 : N1;
01335     SDValue VOp = SelN0 ? N1 : N0;
01336 
01337     if (SOp.getOpcode() == ISD::SELECT && SOp.getNode()->hasOneUse()) {
01338       SDValue SC = SOp.getOperand(0);
01339       SDValue SX = SOp.getOperand(1);
01340       SDValue SY = SOp.getOperand(2);
01341       SDLoc DLS = SOp;
01342       if (IsZero(SY)) {
01343         SDValue NewOr = DAG.getNode(ISD::OR, DLS, VT, SX, VOp);
01344         SDValue NewSel = DAG.getNode(ISD::SELECT, DLS, VT, SC, NewOr, VOp);
01345         DAG.ReplaceAllUsesWith(I, NewSel.getNode());
01346       } else if (IsZero(SX)) {
01347         SDValue NewOr = DAG.getNode(ISD::OR, DLS, VT, SY, VOp);
01348         SDValue NewSel = DAG.getNode(ISD::SELECT, DLS, VT, SC, VOp, NewOr);
01349         DAG.ReplaceAllUsesWith(I, NewSel.getNode());
01350       }
01351     }
01352   }
01353 }
01354 
01355 
01356 bool HexagonDAGToDAGISel::SelectAddrFI(SDValue& N, SDValue &R) {
01357   if (N.getOpcode() != ISD::FrameIndex)
01358     return false;
01359   FrameIndexSDNode *FX = cast<FrameIndexSDNode>(N);
01360   R = CurDAG->getTargetFrameIndex(FX->getIndex(), MVT::i32);
01361   return true;
01362 }
01363 
01364 inline bool HexagonDAGToDAGISel::SelectAddrGA(SDValue &N, SDValue &R) {
01365   return SelectGlobalAddress(N, R, false);
01366 }
01367 
01368 inline bool HexagonDAGToDAGISel::SelectAddrGP(SDValue &N, SDValue &R) {
01369   return SelectGlobalAddress(N, R, true);
01370 }
01371 
01372 bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R,
01373                                               bool UseGP) {
01374   switch (N.getOpcode()) {
01375   case ISD::ADD: {
01376     SDValue N0 = N.getOperand(0);
01377     SDValue N1 = N.getOperand(1);
01378     unsigned GAOpc = N0.getOpcode();
01379     if (UseGP && GAOpc != HexagonISD::CONST32_GP)
01380       return false;
01381     if (!UseGP && GAOpc != HexagonISD::CONST32)
01382       return false;
01383     if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1)) {
01384       SDValue Addr = N0.getOperand(0);
01385       if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Addr)) {
01386         if (GA->getOpcode() == ISD::TargetGlobalAddress) {
01387           uint64_t NewOff = GA->getOffset() + (uint64_t)Const->getSExtValue();
01388           R = CurDAG->getTargetGlobalAddress(GA->getGlobal(), SDLoc(Const),
01389                                              N.getValueType(), NewOff);
01390           return true;
01391         }
01392       }
01393     }
01394     break;
01395   }
01396   case HexagonISD::CONST32:
01397     // The operand(0) of CONST32 is TargetGlobalAddress, which is what we
01398     // want in the instruction.
01399     if (!UseGP)
01400       R = N.getOperand(0);
01401     return !UseGP;
01402   case HexagonISD::CONST32_GP:
01403     if (UseGP)
01404       R = N.getOperand(0);
01405     return UseGP;
01406   default:
01407     return false;
01408   }
01409 
01410   return false;
01411 }
01412 
01413 bool HexagonDAGToDAGISel::isValueExtension(const SDValue &Val,
01414       unsigned FromBits, SDValue &Src) {
01415   unsigned Opc = Val.getOpcode();
01416   switch (Opc) {
01417   case ISD::SIGN_EXTEND:
01418   case ISD::ZERO_EXTEND:
01419   case ISD::ANY_EXTEND: {
01420     SDValue const &Op0 = Val.getOperand(0);
01421     EVT T = Op0.getValueType();
01422     if (T.isInteger() && T.getSizeInBits() == FromBits) {
01423       Src = Op0;
01424       return true;
01425     }
01426     break;
01427   }
01428   case ISD::SIGN_EXTEND_INREG:
01429   case ISD::AssertSext:
01430   case ISD::AssertZext:
01431     if (Val.getOperand(0).getValueType().isInteger()) {
01432       VTSDNode *T = cast<VTSDNode>(Val.getOperand(1));
01433       if (T->getVT().getSizeInBits() == FromBits) {
01434         Src = Val.getOperand(0);
01435         return true;
01436       }
01437     }
01438     break;
01439   case ISD::AND: {
01440     // Check if this is an AND with "FromBits" of lower bits set to 1.
01441     uint64_t FromMask = (1 << FromBits) - 1;
01442     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
01443       if (C->getZExtValue() == FromMask) {
01444         Src = Val.getOperand(1);
01445         return true;
01446       }
01447     }
01448     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
01449       if (C->getZExtValue() == FromMask) {
01450         Src = Val.getOperand(0);
01451         return true;
01452       }
01453     }
01454     break;
01455   }
01456   case ISD::OR:
01457   case ISD::XOR: {
01458     // OR/XOR with the lower "FromBits" bits set to 0.
01459     uint64_t FromMask = (1 << FromBits) - 1;
01460     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
01461       if ((C->getZExtValue() & FromMask) == 0) {
01462         Src = Val.getOperand(1);
01463         return true;
01464       }
01465     }
01466     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
01467       if ((C->getZExtValue() & FromMask) == 0) {
01468         Src = Val.getOperand(0);
01469         return true;
01470       }
01471     }
01472   }
01473   default:
01474     break;
01475   }
01476   return false;
01477 }