LLVM API Documentation

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   /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
00049   /// make the right decision when generating code for different targets.
00050   const HexagonSubtarget &Subtarget;
00051 
00052   // Keep a reference to HexagonTargetMachine.
00053   const HexagonTargetMachine& TM;
00054   DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap;
00055 public:
00056   explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine,
00057                                CodeGenOpt::Level OptLevel)
00058     : SelectionDAGISel(targetmachine, OptLevel),
00059       Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
00060       TM(targetmachine) {
00061     initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
00062   }
00063   bool hasNumUsesBelowThresGA(SDNode *N) const;
00064 
00065   SDNode *Select(SDNode *N) override;
00066 
00067   // Complex Pattern Selectors.
00068   inline bool foldGlobalAddress(SDValue &N, SDValue &R);
00069   inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
00070   bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
00071   bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
00072   bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
00073   bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
00074   bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
00075   bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
00076   bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
00077   bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
00078   bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
00079   bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
00080   bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
00081 
00082   bool SelectAddrFI(SDValue &N, SDValue &R);
00083 
00084   const char *getPassName() const override {
00085     return "Hexagon DAG->DAG Pattern Instruction Selection";
00086   }
00087 
00088   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
00089   /// inline asm expressions.
00090   bool SelectInlineAsmMemoryOperand(const SDValue &Op,
00091                                     char ConstraintCode,
00092                                     std::vector<SDValue> &OutOps) override;
00093   bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
00094 
00095   SDNode *SelectLoad(SDNode *N);
00096   SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl);
00097   SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl);
00098   SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
00099                                         SDLoc dl);
00100   SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
00101                                         SDLoc dl);
00102   SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl);
00103   SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl);
00104   SDNode *SelectStore(SDNode *N);
00105   SDNode *SelectSHL(SDNode *N);
00106   SDNode *SelectSelect(SDNode *N);
00107   SDNode *SelectTruncate(SDNode *N);
00108   SDNode *SelectMul(SDNode *N);
00109   SDNode *SelectZeroExtend(SDNode *N);
00110   SDNode *SelectIntrinsicWOChain(SDNode *N);
00111   SDNode *SelectIntrinsicWChain(SDNode *N);
00112   SDNode *SelectConstant(SDNode *N);
00113   SDNode *SelectConstantFP(SDNode *N);
00114   SDNode *SelectAdd(SDNode *N);
00115   bool isConstExtProfitable(SDNode *N) const;
00116 
00117 // XformMskToBitPosU5Imm - Returns the bit position which
00118 // the single bit 32 bit mask represents.
00119 // Used in Clr and Set bit immediate memops.
00120 SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
00121   int32_t bitPos;
00122   bitPos = Log2_32(Imm);
00123   assert(bitPos >= 0 && bitPos < 32 &&
00124          "Constant out of range for 32 BitPos Memops");
00125   return CurDAG->getTargetConstant(bitPos, MVT::i32);
00126 }
00127 
00128 // XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
00129 // mask represents. Used in Clr and Set bit immediate memops.
00130 SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
00131   return XformMskToBitPosU5Imm(Imm);
00132 }
00133 
00134 // XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
00135 // mask represents. Used in Clr and Set bit immediate memops.
00136 SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
00137   return XformMskToBitPosU5Imm(Imm);
00138 }
00139 
00140 // Return true if there is exactly one bit set in V, i.e., if V is one of the
00141 // following integers: 2^0, 2^1, ..., 2^31.
00142 bool ImmIsSingleBit(uint32_t v) const {
00143   uint32_t c = CountPopulation_64(v);
00144   // Only return true if we counted 1 bit.
00145   return c == 1;
00146 }
00147 
00148 // XformM5ToU5Imm - Return a target constant with the specified value, of type
00149 // i32 where the negative literal is transformed into a positive literal for
00150 // use in -= memops.
00151 inline SDValue XformM5ToU5Imm(signed Imm) {
00152    assert( (Imm >= -31 && Imm <= -1)  && "Constant out of range for Memops");
00153    return CurDAG->getTargetConstant( - Imm, MVT::i32);
00154 }
00155 
00156 
00157 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
00158 // [1..128], used in cmpb.gtu instructions.
00159 inline SDValue XformU7ToU7M1Imm(signed Imm) {
00160   assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
00161   return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
00162 }
00163 
00164 // XformS8ToS8M1Imm - Return a target constant decremented by 1.
00165 inline SDValue XformSToSM1Imm(signed Imm) {
00166   return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
00167 }
00168 
00169 // XformU8ToU8M1Imm - Return a target constant decremented by 1.
00170 inline SDValue XformUToUM1Imm(unsigned Imm) {
00171   assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
00172   return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
00173 }
00174 
00175 // XformSToSM2Imm - Return a target constant decremented by 2.
00176 inline SDValue XformSToSM2Imm(unsigned Imm) {
00177   return CurDAG->getTargetConstant(Imm - 2, MVT::i32);
00178 }
00179 
00180 // XformSToSM3Imm - Return a target constant decremented by 3.
00181 inline SDValue XformSToSM3Imm(unsigned Imm) {
00182   return CurDAG->getTargetConstant(Imm - 3, MVT::i32);
00183 }
00184 
00185 // Include the pieces autogenerated from the target description.
00186 #include "HexagonGenDAGISel.inc"
00187 
00188 private:
00189   bool isValueExtension(SDValue const &Val, unsigned FromBits, SDValue &Src);
00190 };
00191 }  // end anonymous namespace
00192 
00193 
00194 /// createHexagonISelDag - This pass converts a legalized DAG into a
00195 /// Hexagon-specific DAG, ready for instruction scheduling.
00196 ///
00197 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM,
00198                                          CodeGenOpt::Level OptLevel) {
00199   return new HexagonDAGToDAGISel(TM, OptLevel);
00200 }
00201 
00202 static void initializePassOnce(PassRegistry &Registry) {
00203   const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
00204   PassInfo *PI = new PassInfo(Name, "hexagon-isel",
00205                               &SelectionDAGISel::ID, nullptr, false, false);
00206   Registry.registerPass(*PI, true);
00207 }
00208 
00209 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
00210   CALL_ONCE_INITIALIZATION(initializePassOnce)
00211 }
00212 
00213 
00214 static bool IsS11_0_Offset(SDNode * S) {
00215     ConstantSDNode *N = cast<ConstantSDNode>(S);
00216 
00217   // immS16 predicate - True if the immediate fits in a 16-bit sign extended
00218   // field.
00219   int64_t v = (int64_t)N->getSExtValue();
00220   return isInt<11>(v);
00221 }
00222 
00223 
00224 static bool IsS11_1_Offset(SDNode * S) {
00225     ConstantSDNode *N = cast<ConstantSDNode>(S);
00226 
00227   // immS16 predicate - True if the immediate fits in a 16-bit sign extended
00228   // field.
00229   int64_t v = (int64_t)N->getSExtValue();
00230   return isShiftedInt<11,1>(v);
00231 }
00232 
00233 
00234 static bool IsS11_2_Offset(SDNode * S) {
00235     ConstantSDNode *N = cast<ConstantSDNode>(S);
00236 
00237   // immS16 predicate - True if the immediate fits in a 16-bit sign extended
00238   // field.
00239   int64_t v = (int64_t)N->getSExtValue();
00240   return isShiftedInt<11,2>(v);
00241 }
00242 
00243 
00244 static bool IsS11_3_Offset(SDNode * S) {
00245     ConstantSDNode *N = cast<ConstantSDNode>(S);
00246 
00247   // immS16 predicate - True if the immediate fits in a 16-bit sign extended
00248   // field.
00249   int64_t v = (int64_t)N->getSExtValue();
00250   return isShiftedInt<11,3>(v);
00251 }
00252 
00253 
00254 static bool IsU6_0_Offset(SDNode * S) {
00255     ConstantSDNode *N = cast<ConstantSDNode>(S);
00256 
00257   // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
00258   // field.
00259   int64_t v = (int64_t)N->getSExtValue();
00260   return isUInt<6>(v);
00261 }
00262 
00263 
00264 static bool IsU6_1_Offset(SDNode * S) {
00265     ConstantSDNode *N = cast<ConstantSDNode>(S);
00266 
00267   // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
00268   // field.
00269   int64_t v = (int64_t)N->getSExtValue();
00270   return isShiftedUInt<6,1>(v);
00271 }
00272 
00273 
00274 static bool IsU6_2_Offset(SDNode * S) {
00275     ConstantSDNode *N = cast<ConstantSDNode>(S);
00276 
00277   // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
00278   // field.
00279   int64_t v = (int64_t)N->getSExtValue();
00280   return isShiftedUInt<6,2>(v);
00281 }
00282 
00283 
00284 // Intrinsics that return a a predicate.
00285 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
00286 {
00287   switch (ID) {
00288     default:
00289       return 0;
00290     case Intrinsic::hexagon_C2_cmpeq:
00291     case Intrinsic::hexagon_C2_cmpgt:
00292     case Intrinsic::hexagon_C2_cmpgtu:
00293     case Intrinsic::hexagon_C2_cmpgtup:
00294     case Intrinsic::hexagon_C2_cmpgtp:
00295     case Intrinsic::hexagon_C2_cmpeqp:
00296     case Intrinsic::hexagon_C2_bitsset:
00297     case Intrinsic::hexagon_C2_bitsclr:
00298     case Intrinsic::hexagon_C2_cmpeqi:
00299     case Intrinsic::hexagon_C2_cmpgti:
00300     case Intrinsic::hexagon_C2_cmpgtui:
00301     case Intrinsic::hexagon_C2_cmpgei:
00302     case Intrinsic::hexagon_C2_cmpgeui:
00303     case Intrinsic::hexagon_C2_cmplt:
00304     case Intrinsic::hexagon_C2_cmpltu:
00305     case Intrinsic::hexagon_C2_bitsclri:
00306     case Intrinsic::hexagon_C2_and:
00307     case Intrinsic::hexagon_C2_or:
00308     case Intrinsic::hexagon_C2_xor:
00309     case Intrinsic::hexagon_C2_andn:
00310     case Intrinsic::hexagon_C2_not:
00311     case Intrinsic::hexagon_C2_orn:
00312     case Intrinsic::hexagon_C2_pxfer_map:
00313     case Intrinsic::hexagon_C2_any8:
00314     case Intrinsic::hexagon_C2_all8:
00315     case Intrinsic::hexagon_A2_vcmpbeq:
00316     case Intrinsic::hexagon_A2_vcmpbgtu:
00317     case Intrinsic::hexagon_A2_vcmpheq:
00318     case Intrinsic::hexagon_A2_vcmphgt:
00319     case Intrinsic::hexagon_A2_vcmphgtu:
00320     case Intrinsic::hexagon_A2_vcmpweq:
00321     case Intrinsic::hexagon_A2_vcmpwgt:
00322     case Intrinsic::hexagon_A2_vcmpwgtu:
00323     case Intrinsic::hexagon_C2_tfrrp:
00324     case Intrinsic::hexagon_S2_tstbit_i:
00325     case Intrinsic::hexagon_S2_tstbit_r:
00326       return 1;
00327   }
00328 }
00329 
00330 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
00331   if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
00332     return true;
00333   }
00334   if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
00335     return true;
00336   }
00337   if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
00338     return true;
00339   }
00340   if (MemType == MVT::i8 && isInt<11>(Offset)) {
00341     return true;
00342   }
00343   return false;
00344 }
00345 
00346 
00347 //
00348 // Try to lower loads of GlobalAdresses into base+offset loads.  Custom
00349 // lowering for GlobalAddress nodes has already turned it into a
00350 // CONST32.
00351 //
00352 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) {
00353   SDValue Chain = LD->getChain();
00354   SDNode* Const32 = LD->getBasePtr().getNode();
00355   unsigned Opcode = 0;
00356 
00357   if (Const32->getOpcode() == HexagonISD::CONST32 &&
00358       ISD::isNormalLoad(LD)) {
00359     SDValue Base = Const32->getOperand(0);
00360     EVT LoadedVT = LD->getMemoryVT();
00361     int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
00362     if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
00363       MVT PointerTy = getTargetLowering()->getPointerTy();
00364       const GlobalValue* GV =
00365         cast<GlobalAddressSDNode>(Base)->getGlobal();
00366       SDValue TargAddr =
00367         CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
00368       SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
00369                                                dl, PointerTy,
00370                                                TargAddr);
00371       // Figure out base + offset opcode
00372       if (LoadedVT == MVT::i64) Opcode = Hexagon::L2_loadrd_io;
00373       else if (LoadedVT == MVT::i32) Opcode = Hexagon::L2_loadri_io;
00374       else if (LoadedVT == MVT::i16) Opcode = Hexagon::L2_loadrh_io;
00375       else if (LoadedVT == MVT::i8) Opcode = Hexagon::L2_loadrb_io;
00376       else llvm_unreachable("unknown memory type");
00377 
00378       // Build indexed load.
00379       SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
00380       SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
00381                                               LD->getValueType(0),
00382                                               MVT::Other,
00383                                               SDValue(NewBase,0),
00384                                               TargetConstOff,
00385                                               Chain);
00386       MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00387       MemOp[0] = LD->getMemOperand();
00388       cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
00389       ReplaceUses(LD, Result);
00390       return Result;
00391     }
00392   }
00393 
00394   return SelectCode(LD);
00395 }
00396 
00397 
00398 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
00399                                                            unsigned Opcode,
00400                                                            SDLoc dl)
00401 {
00402   SDValue Chain = LD->getChain();
00403   EVT LoadedVT = LD->getMemoryVT();
00404   SDValue Base = LD->getBasePtr();
00405   SDValue Offset = LD->getOffset();
00406   SDNode *OffsetNode = Offset.getNode();
00407   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
00408   SDValue N1 = LD->getOperand(1);
00409   SDValue CPTmpN1_0;
00410   SDValue CPTmpN1_1;
00411 
00412   if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
00413       N1.getNode()->getValueType(0) == MVT::i32) {
00414     const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
00415         TM.getSubtargetImpl()->getInstrInfo());
00416     if (TII->isValidAutoIncImm(LoadedVT, Val)) {
00417       SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
00418       SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
00419                                                 MVT::Other, Base, TargetConst,
00420                                                 Chain);
00421       SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64,
00422                                                 SDValue(Result_1, 0));
00423       MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00424       MemOp[0] = LD->getMemOperand();
00425       cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00426       const SDValue Froms[] = { SDValue(LD, 0),
00427                                 SDValue(LD, 1),
00428                                 SDValue(LD, 2)
00429       };
00430       const SDValue Tos[]   = { SDValue(Result_2, 0),
00431                                 SDValue(Result_1, 1),
00432                                 SDValue(Result_1, 2)
00433       };
00434       ReplaceUses(Froms, Tos, 3);
00435       return Result_2;
00436     }
00437     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00438     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00439     SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
00440                                               MVT::Other, Base, TargetConst0,
00441                                               Chain);
00442     SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl,
00443                                                 MVT::i64, SDValue(Result_1, 0));
00444     SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
00445                                               MVT::i32, Base, TargetConstVal,
00446                                                 SDValue(Result_1, 1));
00447     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00448     MemOp[0] = LD->getMemOperand();
00449     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00450     const SDValue Froms[] = { SDValue(LD, 0),
00451                               SDValue(LD, 1),
00452                               SDValue(LD, 2)
00453     };
00454     const SDValue Tos[]   = { SDValue(Result_2, 0),
00455                               SDValue(Result_3, 0),
00456                               SDValue(Result_1, 1)
00457     };
00458     ReplaceUses(Froms, Tos, 3);
00459     return Result_2;
00460   }
00461   return SelectCode(LD);
00462 }
00463 
00464 
00465 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
00466                                                            unsigned Opcode,
00467                                                            SDLoc dl)
00468 {
00469   SDValue Chain = LD->getChain();
00470   EVT LoadedVT = LD->getMemoryVT();
00471   SDValue Base = LD->getBasePtr();
00472   SDValue Offset = LD->getOffset();
00473   SDNode *OffsetNode = Offset.getNode();
00474   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
00475   SDValue N1 = LD->getOperand(1);
00476   SDValue CPTmpN1_0;
00477   SDValue CPTmpN1_1;
00478 
00479   if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
00480       N1.getNode()->getValueType(0) == MVT::i32) {
00481     const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
00482         TM.getSubtargetImpl()->getInstrInfo());
00483     if (TII->isValidAutoIncImm(LoadedVT, Val)) {
00484       SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00485       SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00486       SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
00487                                                 MVT::i32, MVT::Other, Base,
00488                                                 TargetConstVal, Chain);
00489       SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
00490                                                 TargetConst0);
00491       SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
00492                                                 MVT::i64, MVT::Other,
00493                                                 SDValue(Result_2,0),
00494                                                 SDValue(Result_1,0));
00495       MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00496       MemOp[0] = LD->getMemOperand();
00497       cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00498       const SDValue Froms[] = { SDValue(LD, 0),
00499                                 SDValue(LD, 1),
00500                                 SDValue(LD, 2)
00501       };
00502       const SDValue Tos[]   = { SDValue(Result_3, 0),
00503                                 SDValue(Result_1, 1),
00504                                 SDValue(Result_1, 2)
00505       };
00506       ReplaceUses(Froms, Tos, 3);
00507       return Result_3;
00508     }
00509 
00510     // Generate an indirect load.
00511     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00512     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00513     SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
00514                                               MVT::Other,
00515                                               Base, TargetConst0, Chain);
00516     SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
00517                                               TargetConst0);
00518     SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
00519                                               MVT::i64, MVT::Other,
00520                                               SDValue(Result_2,0),
00521                                               SDValue(Result_1,0));
00522     // Add offset to base.
00523     SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
00524                                               Base, TargetConstVal,
00525                                               SDValue(Result_1, 1));
00526     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00527     MemOp[0] = LD->getMemOperand();
00528     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00529     const SDValue Froms[] = { SDValue(LD, 0),
00530                               SDValue(LD, 1),
00531                               SDValue(LD, 2)
00532     };
00533     const SDValue Tos[]   = { SDValue(Result_3, 0), // Load value.
00534                               SDValue(Result_4, 0), // New address.
00535                               SDValue(Result_1, 1)
00536     };
00537     ReplaceUses(Froms, Tos, 3);
00538     return Result_3;
00539   }
00540 
00541   return SelectCode(LD);
00542 }
00543 
00544 
00545 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
00546   SDValue Chain = LD->getChain();
00547   SDValue Base = LD->getBasePtr();
00548   SDValue Offset = LD->getOffset();
00549   SDNode *OffsetNode = Offset.getNode();
00550   // Get the constant value.
00551   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
00552   EVT LoadedVT = LD->getMemoryVT();
00553   unsigned Opcode = 0;
00554 
00555   // Check for zero ext loads.
00556   bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
00557 
00558   // Figure out the opcode.
00559   const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
00560       TM.getSubtargetImpl()->getInstrInfo());
00561   if (LoadedVT == MVT::i64) {
00562     if (TII->isValidAutoIncImm(LoadedVT, Val))
00563       Opcode = Hexagon::L2_loadrd_pi;
00564     else
00565       Opcode = Hexagon::L2_loadrd_io;
00566   } else if (LoadedVT == MVT::i32) {
00567     if (TII->isValidAutoIncImm(LoadedVT, Val))
00568       Opcode = Hexagon::L2_loadri_pi;
00569     else
00570       Opcode = Hexagon::L2_loadri_io;
00571   } else if (LoadedVT == MVT::i16) {
00572     if (TII->isValidAutoIncImm(LoadedVT, Val))
00573       Opcode = zextval ? Hexagon::L2_loadruh_pi : Hexagon::L2_loadrh_pi;
00574     else
00575       Opcode = zextval ? Hexagon::L2_loadruh_io : Hexagon::L2_loadrh_io;
00576   } else if (LoadedVT == MVT::i8) {
00577     if (TII->isValidAutoIncImm(LoadedVT, Val))
00578       Opcode = zextval ? Hexagon::L2_loadrub_pi : Hexagon::L2_loadrb_pi;
00579     else
00580       Opcode = zextval ? Hexagon::L2_loadrub_io : Hexagon::L2_loadrb_io;
00581   } else
00582     llvm_unreachable("unknown memory type");
00583 
00584   // For zero ext i64 loads, we need to add combine instructions.
00585   if (LD->getValueType(0) == MVT::i64 &&
00586       LD->getExtensionType() == ISD::ZEXTLOAD) {
00587     return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
00588   }
00589   if (LD->getValueType(0) == MVT::i64 &&
00590              LD->getExtensionType() == ISD::SEXTLOAD) {
00591     // Handle sign ext i64 loads.
00592     return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
00593   }
00594   if (TII->isValidAutoIncImm(LoadedVT, Val)) {
00595     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00596     SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
00597                                             LD->getValueType(0),
00598                                             MVT::i32, MVT::Other, Base,
00599                                             TargetConstVal, Chain);
00600     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00601     MemOp[0] = LD->getMemOperand();
00602     cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
00603     const SDValue Froms[] = { SDValue(LD, 0),
00604                               SDValue(LD, 1),
00605                               SDValue(LD, 2)
00606     };
00607     const SDValue Tos[]   = { SDValue(Result, 0),
00608                               SDValue(Result, 1),
00609                               SDValue(Result, 2)
00610     };
00611     ReplaceUses(Froms, Tos, 3);
00612     return Result;
00613   } else {
00614     SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00615     SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00616     SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
00617                                               LD->getValueType(0),
00618                                               MVT::Other, Base, TargetConst0,
00619                                               Chain);
00620     SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
00621                                               Base, TargetConstVal,
00622                                               SDValue(Result_1, 1));
00623     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00624     MemOp[0] = LD->getMemOperand();
00625     cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00626     const SDValue Froms[] = { SDValue(LD, 0),
00627                               SDValue(LD, 1),
00628                               SDValue(LD, 2)
00629     };
00630     const SDValue Tos[]   = { SDValue(Result_1, 0),
00631                               SDValue(Result_2, 0),
00632                               SDValue(Result_1, 1)
00633     };
00634     ReplaceUses(Froms, Tos, 3);
00635     return Result_1;
00636   }
00637 }
00638 
00639 
00640 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
00641   SDNode *result;
00642   SDLoc dl(N);
00643   LoadSDNode *LD = cast<LoadSDNode>(N);
00644   ISD::MemIndexedMode AM = LD->getAddressingMode();
00645 
00646   // Handle indexed loads.
00647   if (AM != ISD::UNINDEXED) {
00648     result = SelectIndexedLoad(LD, dl);
00649   } else {
00650     result = SelectBaseOffsetLoad(LD, dl);
00651   }
00652 
00653   return result;
00654 }
00655 
00656 
00657 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
00658   SDValue Chain = ST->getChain();
00659   SDValue Base = ST->getBasePtr();
00660   SDValue Offset = ST->getOffset();
00661   SDValue Value = ST->getValue();
00662   SDNode *OffsetNode = Offset.getNode();
00663   // Get the constant value.
00664   int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
00665   EVT StoredVT = ST->getMemoryVT();
00666 
00667   // Offset value must be within representable range
00668   // and must have correct alignment properties.
00669   const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
00670       TM.getSubtargetImpl()->getInstrInfo());
00671   if (TII->isValidAutoIncImm(StoredVT, Val)) {
00672     SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
00673                      Chain};
00674     unsigned Opcode = 0;
00675 
00676     // Figure out the post inc version of opcode.
00677     if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_pi;
00678     else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_pi;
00679     else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_pi;
00680     else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_pi;
00681     else llvm_unreachable("unknown memory type");
00682 
00683     // Build post increment store.
00684     SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
00685                                             MVT::Other, Ops);
00686     MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00687     MemOp[0] = ST->getMemOperand();
00688     cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
00689 
00690     ReplaceUses(ST, Result);
00691     ReplaceUses(SDValue(ST,1), SDValue(Result,1));
00692     return Result;
00693   }
00694 
00695   // Note: Order of operands matches the def of instruction:
00696   // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
00697   // and it differs for POST_ST* for instance.
00698   SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
00699                     Chain};
00700   unsigned Opcode = 0;
00701 
00702   // Figure out the opcode.
00703   if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
00704   else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
00705   else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
00706   else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
00707   else llvm_unreachable("unknown memory type");
00708 
00709   // Build regular store.
00710   SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
00711   SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
00712   // Build splitted incriment instruction.
00713   SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
00714                                             Base,
00715                                             TargetConstVal,
00716                                             SDValue(Result_1, 0));
00717   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00718   MemOp[0] = ST->getMemOperand();
00719   cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
00720 
00721   ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
00722   ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
00723   return Result_2;
00724 }
00725 
00726 
00727 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
00728                                                    SDLoc dl) {
00729   SDValue Chain = ST->getChain();
00730   SDNode* Const32 = ST->getBasePtr().getNode();
00731   SDValue Value = ST->getValue();
00732   unsigned Opcode = 0;
00733 
00734   // Try to lower stores of GlobalAdresses into indexed stores.  Custom
00735   // lowering for GlobalAddress nodes has already turned it into a
00736   // CONST32.  Avoid truncating stores for the moment.  Post-inc stores
00737   // do the same.  Don't think there's a reason for it, so will file a
00738   // bug to fix.
00739   if ((Const32->getOpcode() == HexagonISD::CONST32) &&
00740       !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
00741     SDValue Base = Const32->getOperand(0);
00742     if (Base.getOpcode() == ISD::TargetGlobalAddress) {
00743       EVT StoredVT = ST->getMemoryVT();
00744       int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
00745       if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
00746         MVT PointerTy = getTargetLowering()->getPointerTy();
00747         const GlobalValue* GV =
00748           cast<GlobalAddressSDNode>(Base)->getGlobal();
00749         SDValue TargAddr =
00750           CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
00751         SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
00752                                                  dl, PointerTy,
00753                                                  TargAddr);
00754 
00755         // Figure out base + offset opcode
00756         if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
00757         else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
00758         else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
00759         else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
00760         else llvm_unreachable("unknown memory type");
00761 
00762         SDValue Ops[] = {SDValue(NewBase,0),
00763                          CurDAG->getTargetConstant(Offset,PointerTy),
00764                          Value, Chain};
00765         // build indexed store
00766         SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
00767                                                 MVT::Other, Ops);
00768         MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
00769         MemOp[0] = ST->getMemOperand();
00770         cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
00771         ReplaceUses(ST, Result);
00772         return Result;
00773       }
00774     }
00775   }
00776 
00777   return SelectCode(ST);
00778 }
00779 
00780 
00781 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
00782   SDLoc dl(N);
00783   StoreSDNode *ST = cast<StoreSDNode>(N);
00784   ISD::MemIndexedMode AM = ST->getAddressingMode();
00785 
00786   // Handle indexed stores.
00787   if (AM != ISD::UNINDEXED) {
00788     return SelectIndexedStore(ST, dl);
00789   }
00790 
00791   return SelectBaseOffsetStore(ST, dl);
00792 }
00793 
00794 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
00795   SDLoc dl(N);
00796 
00797   //
00798   // %conv.i = sext i32 %tmp1 to i64
00799   // %conv2.i = sext i32 %add to i64
00800   // %mul.i = mul nsw i64 %conv2.i, %conv.i
00801   //
00802   //   --- match with the following ---
00803   //
00804   // %mul.i = mpy (%tmp1, %add)
00805   //
00806 
00807   if (N->getValueType(0) == MVT::i64) {
00808     // Shifting a i64 signed multiply.
00809     SDValue MulOp0 = N->getOperand(0);
00810     SDValue MulOp1 = N->getOperand(1);
00811 
00812     SDValue OP0;
00813     SDValue OP1;
00814 
00815     // Handle sign_extend and sextload.
00816     if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
00817       SDValue Sext0 = MulOp0.getOperand(0);
00818       if (Sext0.getNode()->getValueType(0) != MVT::i32) {
00819         return SelectCode(N);
00820       }
00821 
00822       OP0 = Sext0;
00823     } else if (MulOp0.getOpcode() == ISD::LOAD) {
00824       LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
00825       if (LD->getMemoryVT() != MVT::i32 ||
00826           LD->getExtensionType() != ISD::SEXTLOAD ||
00827           LD->getAddressingMode() != ISD::UNINDEXED) {
00828         return SelectCode(N);
00829       }
00830 
00831       SDValue Chain = LD->getChain();
00832       SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00833       OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
00834                                             MVT::Other,
00835                                             LD->getBasePtr(), TargetConst0,
00836                                             Chain), 0);
00837     } else {
00838       return SelectCode(N);
00839     }
00840 
00841     // Same goes for the second operand.
00842     if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
00843       SDValue Sext1 = MulOp1.getOperand(0);
00844       if (Sext1.getNode()->getValueType(0) != MVT::i32) {
00845         return SelectCode(N);
00846       }
00847 
00848       OP1 = Sext1;
00849     } else if (MulOp1.getOpcode() == ISD::LOAD) {
00850       LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
00851       if (LD->getMemoryVT() != MVT::i32 ||
00852           LD->getExtensionType() != ISD::SEXTLOAD ||
00853           LD->getAddressingMode() != ISD::UNINDEXED) {
00854         return SelectCode(N);
00855       }
00856 
00857       SDValue Chain = LD->getChain();
00858       SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
00859       OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
00860                                             MVT::Other,
00861                                             LD->getBasePtr(), TargetConst0,
00862                                             Chain), 0);
00863     } else {
00864       return SelectCode(N);
00865     }
00866 
00867     // Generate a mpy instruction.
00868     SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl, MVT::i64,
00869                                             OP0, OP1);
00870     ReplaceUses(N, Result);
00871     return Result;
00872   }
00873 
00874   return SelectCode(N);
00875 }
00876 
00877 
00878 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
00879   SDLoc dl(N);
00880   SDValue N0 = N->getOperand(0);
00881   if (N0.getOpcode() == ISD::SETCC) {
00882     SDValue N00 = N0.getOperand(0);
00883     if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
00884       SDValue N000 = N00.getOperand(0);
00885       SDValue N001 = N00.getOperand(1);
00886       if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
00887         SDValue N01 = N0.getOperand(1);
00888         SDValue N02 = N0.getOperand(2);
00889 
00890         // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
00891         // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
00892         // IntRegs:i32:$src2)
00893         // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
00894         // Pattern complexity = 9  cost = 1  size = 0.
00895         if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
00896           SDValue N1 = N->getOperand(1);
00897           if (N01 == N1) {
00898             SDValue N2 = N->getOperand(2);
00899             if (N000 == N2 &&
00900                 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
00901                 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
00902               SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
00903                                                         MVT::i32, N000);
00904               SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_max, dl,
00905                                                       MVT::i32,
00906                                                       SDValue(SextNode, 0),
00907                                                       N1);
00908               ReplaceUses(N, Result);
00909               return Result;
00910             }
00911           }
00912         }
00913 
00914         // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
00915         // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
00916         // IntRegs:i32:$src2)
00917         // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
00918         // Pattern complexity = 9  cost = 1  size = 0.
00919         if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
00920           SDValue N1 = N->getOperand(1);
00921           if (N01 == N1) {
00922             SDValue N2 = N->getOperand(2);
00923             if (N000 == N2 &&
00924                 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
00925                 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
00926               SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
00927                                                         MVT::i32, N000);
00928               SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_min, dl,
00929                                                       MVT::i32,
00930                                                       SDValue(SextNode, 0),
00931                                                       N1);
00932               ReplaceUses(N, Result);
00933               return Result;
00934             }
00935           }
00936         }
00937       }
00938     }
00939   }
00940 
00941   return SelectCode(N);
00942 }
00943 
00944 
00945 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
00946   SDLoc dl(N);
00947   SDValue Shift = N->getOperand(0);
00948 
00949   //
00950   // %conv.i = sext i32 %tmp1 to i64
00951   // %conv2.i = sext i32 %add to i64
00952   // %mul.i = mul nsw i64 %conv2.i, %conv.i
00953   // %shr5.i = lshr i64 %mul.i, 32
00954   // %conv3.i = trunc i64 %shr5.i to i32
00955   //
00956   //   --- match with the following ---
00957   //
00958   // %conv3.i = mpy (%tmp1, %add)
00959   //
00960   // Trunc to i32.
00961   if (N->getValueType(0) == MVT::i32) {
00962     // Trunc from i64.
00963     if (Shift.getNode()->getValueType(0) == MVT::i64) {
00964       // Trunc child is logical shift right.
00965       if (Shift.getOpcode() != ISD::SRL) {
00966         return SelectCode(N);
00967       }
00968 
00969       SDValue ShiftOp0 = Shift.getOperand(0);
00970       SDValue ShiftOp1 = Shift.getOperand(1);
00971 
00972       // Shift by const 32
00973       if (ShiftOp1.getOpcode() != ISD::Constant) {
00974         return SelectCode(N);
00975       }
00976 
00977       int32_t ShiftConst =
00978         cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
00979       if (ShiftConst != 32) {
00980         return SelectCode(N);
00981       }
00982 
00983       // Shifting a i64 signed multiply
00984       SDValue Mul = ShiftOp0;
00985       if (Mul.getOpcode() != ISD::MUL) {
00986         return SelectCode(N);
00987       }
00988 
00989       SDValue MulOp0 = Mul.getOperand(0);
00990       SDValue MulOp1 = Mul.getOperand(1);
00991 
00992       SDValue OP0;
00993       SDValue OP1;
00994 
00995       // Handle sign_extend and sextload
00996       if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
00997         SDValue Sext0 = MulOp0.getOperand(0);
00998         if (Sext0.getNode()->getValueType(0) != MVT::i32) {
00999           return SelectCode(N);
01000         }
01001 
01002         OP0 = Sext0;
01003       } else if (MulOp0.getOpcode() == ISD::LOAD) {
01004         LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
01005         if (LD->getMemoryVT() != MVT::i32 ||
01006             LD->getExtensionType() != ISD::SEXTLOAD ||
01007             LD->getAddressingMode() != ISD::UNINDEXED) {
01008           return SelectCode(N);
01009         }
01010 
01011         SDValue Chain = LD->getChain();
01012         SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
01013         OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
01014                                               MVT::Other,
01015                                               LD->getBasePtr(),
01016                                               TargetConst0, Chain), 0);
01017       } else {
01018         return SelectCode(N);
01019       }
01020 
01021       // Same goes for the second operand.
01022       if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
01023         SDValue Sext1 = MulOp1.getOperand(0);
01024         if (Sext1.getNode()->getValueType(0) != MVT::i32)
01025           return SelectCode(N);
01026 
01027         OP1 = Sext1;
01028       } else if (MulOp1.getOpcode() == ISD::LOAD) {
01029         LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
01030         if (LD->getMemoryVT() != MVT::i32 ||
01031             LD->getExtensionType() != ISD::SEXTLOAD ||
01032             LD->getAddressingMode() != ISD::UNINDEXED) {
01033           return SelectCode(N);
01034         }
01035 
01036         SDValue Chain = LD->getChain();
01037         SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
01038         OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
01039                                               MVT::Other,
01040                                               LD->getBasePtr(),
01041                                               TargetConst0, Chain), 0);
01042       } else {
01043         return SelectCode(N);
01044       }
01045 
01046       // Generate a mpy instruction.
01047       SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_mpy_up, dl, MVT::i32,
01048                                               OP0, OP1);
01049       ReplaceUses(N, Result);
01050       return Result;
01051     }
01052   }
01053 
01054   return SelectCode(N);
01055 }
01056 
01057 
01058 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
01059   SDLoc dl(N);
01060   if (N->getValueType(0) == MVT::i32) {
01061     SDValue Shl_0 = N->getOperand(0);
01062     SDValue Shl_1 = N->getOperand(1);
01063     // RHS is const.
01064     if (Shl_1.getOpcode() == ISD::Constant) {
01065       if (Shl_0.getOpcode() == ISD::MUL) {
01066         SDValue Mul_0 = Shl_0.getOperand(0); // Val
01067         SDValue Mul_1 = Shl_0.getOperand(1); // Const
01068         // RHS of mul is const.
01069         if (Mul_1.getOpcode() == ISD::Constant) {
01070           int32_t ShlConst =
01071             cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
01072           int32_t MulConst =
01073             cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
01074           int32_t ValConst = MulConst << ShlConst;
01075           SDValue Val = CurDAG->getTargetConstant(ValConst,
01076                                                   MVT::i32);
01077           if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
01078             if (isInt<9>(CN->getSExtValue())) {
01079               SDNode* Result =
01080                 CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
01081                                        MVT::i32, Mul_0, Val);
01082               ReplaceUses(N, Result);
01083               return Result;
01084             }
01085 
01086         }
01087       } else if (Shl_0.getOpcode() == ISD::SUB) {
01088         SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
01089         SDValue Sub_1 = Shl_0.getOperand(1); // Val
01090         if (Sub_0.getOpcode() == ISD::Constant) {
01091           int32_t SubConst =
01092             cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
01093           if (SubConst == 0) {
01094             if (Sub_1.getOpcode() == ISD::SHL) {
01095               SDValue Shl2_0 = Sub_1.getOperand(0); // Val
01096               SDValue Shl2_1 = Sub_1.getOperand(1); // Const
01097               if (Shl2_1.getOpcode() == ISD::Constant) {
01098                 int32_t ShlConst =
01099                   cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
01100                 int32_t Shl2Const =
01101                   cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
01102                 int32_t ValConst = 1 << (ShlConst+Shl2Const);
01103                 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
01104                 if (ConstantSDNode *CN =
01105                     dyn_cast<ConstantSDNode>(Val.getNode()))
01106                   if (isInt<9>(CN->getSExtValue())) {
01107                     SDNode* Result =
01108                       CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, MVT::i32,
01109                                              Shl2_0, Val);
01110                     ReplaceUses(N, Result);
01111                     return Result;
01112                   }
01113               }
01114             }
01115           }
01116         }
01117       }
01118     }
01119   }
01120   return SelectCode(N);
01121 }
01122 
01123 
01124 //
01125 // If there is an zero_extend followed an intrinsic in DAG (this means - the
01126 // result of the intrinsic is predicate); convert the zero_extend to
01127 // transfer instruction.
01128 //
01129 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
01130 // converted into a MUX as predicate registers defined as 1 bit in the
01131 // compiler. Architecture defines them as 8-bit registers.
01132 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
01133 //
01134 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
01135   SDLoc dl(N);
01136   SDNode *IsIntrinsic = N->getOperand(0).getNode();
01137   if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
01138     unsigned ID =
01139       cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
01140     if (doesIntrinsicReturnPredicate(ID)) {
01141       // Now we need to differentiate target data types.
01142       if (N->getValueType(0) == MVT::i64) {
01143         // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
01144         SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
01145         SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
01146                                                   MVT::i32,
01147                                                   SDValue(IsIntrinsic, 0));
01148         SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl,
01149                                                   MVT::i32,
01150                                                   TargetConst0);
01151         SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
01152                                                   MVT::i64, MVT::Other,
01153                                                   SDValue(Result_2, 0),
01154                                                   SDValue(Result_1, 0));
01155         ReplaceUses(N, Result_3);
01156         return Result_3;
01157       }
01158       if (N->getValueType(0) == MVT::i32) {
01159         // Convert the zero_extend to Rs = Pd
01160         SDNode* RsPd = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
01161                                               MVT::i32,
01162                                               SDValue(IsIntrinsic, 0));
01163         ReplaceUses(N, RsPd);
01164         return RsPd;
01165       }
01166       llvm_unreachable("Unexpected value type");
01167     }
01168   }
01169   return SelectCode(N);
01170 }
01171 
01172 //
01173 // Checking for intrinsics which have predicate registers as operand(s)
01174 // and lowering to the actual intrinsic.
01175 //
01176 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
01177   unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
01178   unsigned Bits;
01179   switch (IID) {
01180   case Intrinsic::hexagon_S2_vsplatrb:
01181     Bits = 8;
01182     break;
01183   case Intrinsic::hexagon_S2_vsplatrh:
01184     Bits = 16;
01185     break;
01186   default:
01187     return SelectCode(N);
01188   }
01189 
01190   SDValue const &V = N->getOperand(1);
01191   SDValue U;
01192   if (isValueExtension(V, Bits, U)) {
01193     SDValue R = CurDAG->getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
01194       N->getOperand(0), U);
01195     return SelectCode(R.getNode());
01196   }
01197   return SelectCode(N);
01198 }
01199 
01200 //
01201 // Map floating point constant values.
01202 //
01203 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
01204   SDLoc dl(N);
01205   ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
01206   APFloat APF = CN->getValueAPF();
01207   if (N->getValueType(0) == MVT::f32) {
01208     return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
01209               CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
01210   }
01211   else if (N->getValueType(0) == MVT::f64) {
01212     return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
01213               CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
01214   }
01215 
01216   return SelectCode(N);
01217 }
01218 
01219 
01220 //
01221 // Map predicate true (encoded as -1 in LLVM) to a XOR.
01222 //
01223 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
01224   SDLoc dl(N);
01225   if (N->getValueType(0) == MVT::i1) {
01226     SDNode* Result;
01227     int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
01228     if (Val == -1) {
01229       // Create the IntReg = 1 node.
01230       SDNode* IntRegTFR =
01231         CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
01232                                CurDAG->getTargetConstant(0, MVT::i32));
01233 
01234       // Pd = IntReg
01235       SDNode* Pd = CurDAG->getMachineNode(Hexagon::C2_tfrrp, dl, MVT::i1,
01236                                           SDValue(IntRegTFR, 0));
01237 
01238       // not(Pd)
01239       SDNode* NotPd = CurDAG->getMachineNode(Hexagon::C2_not, dl, MVT::i1,
01240                                              SDValue(Pd, 0));
01241 
01242       // xor(not(Pd))
01243       Result = CurDAG->getMachineNode(Hexagon::C2_xor, dl, MVT::i1,
01244                                       SDValue(Pd, 0), SDValue(NotPd, 0));
01245 
01246       // We have just built:
01247       // Rs = Pd
01248       // Pd = xor(not(Pd), Pd)
01249 
01250       ReplaceUses(N, Result);
01251       return Result;
01252     }
01253   }
01254 
01255   return SelectCode(N);
01256 }
01257 
01258 
01259 //
01260 // Map add followed by a asr -> asr +=.
01261 //
01262 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
01263   SDLoc dl(N);
01264   if (N->getValueType(0) != MVT::i32) {
01265     return SelectCode(N);
01266   }
01267   // Identify nodes of the form: add(asr(...)).
01268   SDNode* Src1 = N->getOperand(0).getNode();
01269   if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
01270       || Src1->getValueType(0) != MVT::i32) {
01271     return SelectCode(N);
01272   }
01273 
01274   // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
01275   // Rd and Rd' are assigned to the same register
01276   SDNode* Result = CurDAG->getMachineNode(Hexagon::S2_asr_r_r_acc, dl, MVT::i32,
01277                                           N->getOperand(1),
01278                                           Src1->getOperand(0),
01279                                           Src1->getOperand(1));
01280   ReplaceUses(N, Result);
01281 
01282   return Result;
01283 }
01284 
01285 
01286 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
01287   if (N->isMachineOpcode()) {
01288     N->setNodeId(-1);
01289     return nullptr;   // Already selected.
01290   }
01291 
01292 
01293   switch (N->getOpcode()) {
01294   case ISD::Constant:
01295     return SelectConstant(N);
01296 
01297   case ISD::ConstantFP:
01298     return SelectConstantFP(N);
01299 
01300   case ISD::ADD:
01301     return SelectAdd(N);
01302 
01303   case ISD::SHL:
01304     return SelectSHL(N);
01305 
01306   case ISD::LOAD:
01307     return SelectLoad(N);
01308 
01309   case ISD::STORE:
01310     return SelectStore(N);
01311 
01312   case ISD::SELECT:
01313     return SelectSelect(N);
01314 
01315   case ISD::TRUNCATE:
01316     return SelectTruncate(N);
01317 
01318   case ISD::MUL:
01319     return SelectMul(N);
01320 
01321   case ISD::ZERO_EXTEND:
01322     return SelectZeroExtend(N);
01323 
01324   case ISD::INTRINSIC_WO_CHAIN:
01325     return SelectIntrinsicWOChain(N);
01326   }
01327 
01328   return SelectCode(N);
01329 }
01330 
01331 
01332 //
01333 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
01334 // to define these instructions.
01335 //
01336 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
01337                                        SDValue &Offset) {
01338   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01339       Addr.getOpcode() == ISD::TargetGlobalAddress)
01340     return false;  // Direct calls.
01341 
01342   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
01343     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
01344     Offset = CurDAG->getTargetConstant(0, MVT::i32);
01345     return true;
01346   }
01347   Base = Addr;
01348   Offset = CurDAG->getTargetConstant(0, MVT::i32);
01349   return true;
01350 }
01351 
01352 
01353 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
01354                                             SDValue &Offset) {
01355   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01356       Addr.getOpcode() == ISD::TargetGlobalAddress)
01357     return false;  // Direct calls.
01358 
01359   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
01360     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
01361     Offset = CurDAG->getTargetConstant(0, MVT::i32);
01362     return (IsS11_0_Offset(Offset.getNode()));
01363   }
01364   Base = Addr;
01365   Offset = CurDAG->getTargetConstant(0, MVT::i32);
01366   return (IsS11_0_Offset(Offset.getNode()));
01367 }
01368 
01369 
01370 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
01371                                             SDValue &Offset) {
01372   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01373       Addr.getOpcode() == ISD::TargetGlobalAddress)
01374     return false;  // Direct calls.
01375 
01376   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
01377     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
01378     Offset = CurDAG->getTargetConstant(0, MVT::i32);
01379     return (IsS11_1_Offset(Offset.getNode()));
01380   }
01381   Base = Addr;
01382   Offset = CurDAG->getTargetConstant(0, MVT::i32);
01383   return (IsS11_1_Offset(Offset.getNode()));
01384 }
01385 
01386 
01387 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
01388                                             SDValue &Offset) {
01389   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01390       Addr.getOpcode() == ISD::TargetGlobalAddress)
01391     return false;  // Direct calls.
01392 
01393   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
01394     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
01395     Offset = CurDAG->getTargetConstant(0, MVT::i32);
01396     return (IsS11_2_Offset(Offset.getNode()));
01397   }
01398   Base = Addr;
01399   Offset = CurDAG->getTargetConstant(0, MVT::i32);
01400   return (IsS11_2_Offset(Offset.getNode()));
01401 }
01402 
01403 
01404 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
01405                                             SDValue &Offset) {
01406   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01407       Addr.getOpcode() == ISD::TargetGlobalAddress)
01408     return false;  // Direct calls.
01409 
01410   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
01411     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
01412     Offset = CurDAG->getTargetConstant(0, MVT::i32);
01413     return (IsU6_0_Offset(Offset.getNode()));
01414   }
01415   Base = Addr;
01416   Offset = CurDAG->getTargetConstant(0, MVT::i32);
01417   return (IsU6_0_Offset(Offset.getNode()));
01418 }
01419 
01420 
01421 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
01422                                             SDValue &Offset) {
01423   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01424       Addr.getOpcode() == ISD::TargetGlobalAddress)
01425     return false;  // Direct calls.
01426 
01427   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
01428     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
01429     Offset = CurDAG->getTargetConstant(0, MVT::i32);
01430     return (IsU6_1_Offset(Offset.getNode()));
01431   }
01432   Base = Addr;
01433   Offset = CurDAG->getTargetConstant(0, MVT::i32);
01434   return (IsU6_1_Offset(Offset.getNode()));
01435 }
01436 
01437 
01438 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
01439                                             SDValue &Offset) {
01440   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01441       Addr.getOpcode() == ISD::TargetGlobalAddress)
01442     return false;  // Direct calls.
01443 
01444   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
01445     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
01446     Offset = CurDAG->getTargetConstant(0, MVT::i32);
01447     return (IsU6_2_Offset(Offset.getNode()));
01448   }
01449   Base = Addr;
01450   Offset = CurDAG->getTargetConstant(0, MVT::i32);
01451   return (IsU6_2_Offset(Offset.getNode()));
01452 }
01453 
01454 
01455 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
01456                                            SDValue &Offset) {
01457 
01458   if (Addr.getOpcode() != ISD::ADD) {
01459     return(SelectADDRriS11_2(Addr, Base, Offset));
01460   }
01461 
01462   return SelectADDRriS11_2(Addr, Base, Offset);
01463 }
01464 
01465 
01466 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
01467                                             SDValue &Offset) {
01468   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01469       Addr.getOpcode() == ISD::TargetGlobalAddress)
01470     return false;  // Direct calls.
01471 
01472   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
01473     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
01474     Offset = CurDAG->getTargetConstant(0, MVT::i32);
01475     return (IsS11_3_Offset(Offset.getNode()));
01476   }
01477   Base = Addr;
01478   Offset = CurDAG->getTargetConstant(0, MVT::i32);
01479   return (IsS11_3_Offset(Offset.getNode()));
01480 }
01481 
01482 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
01483                                        SDValue &R2) {
01484   if (Addr.getOpcode() == ISD::FrameIndex) return false;
01485   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01486       Addr.getOpcode() == ISD::TargetGlobalAddress)
01487     return false;  // Direct calls.
01488 
01489   if (Addr.getOpcode() == ISD::ADD) {
01490     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
01491       if (isInt<13>(CN->getSExtValue()))
01492         return false;  // Let the reg+imm pattern catch this!
01493     R1 = Addr.getOperand(0);
01494     R2 = Addr.getOperand(1);
01495     return true;
01496   }
01497 
01498   R1 = Addr;
01499 
01500   return true;
01501 }
01502 
01503 
01504 // Handle generic address case. It is accessed from inlined asm =m constraints,
01505 // which could have any kind of pointer.
01506 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
01507                                           SDValue &Base, SDValue &Offset) {
01508   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
01509       Addr.getOpcode() == ISD::TargetGlobalAddress)
01510     return false;  // Direct calls.
01511 
01512   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
01513     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
01514     Offset = CurDAG->getTargetConstant(0, MVT::i32);
01515     return true;
01516   }
01517 
01518   if (Addr.getOpcode() == ISD::ADD) {
01519     Base = Addr.getOperand(0);
01520     Offset = Addr.getOperand(1);
01521     return true;
01522   }
01523 
01524   Base = Addr;
01525   Offset = CurDAG->getTargetConstant(0, MVT::i32);
01526   return true;
01527 }
01528 
01529 
01530 bool HexagonDAGToDAGISel::
01531 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
01532                              std::vector<SDValue> &OutOps) {
01533   SDValue Op0, Op1;
01534 
01535   switch (ConstraintCode) {
01536   case 'o':   // Offsetable.
01537   case 'v':   // Not offsetable.
01538   default: return true;
01539   case 'm':   // Memory.
01540     if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
01541       return true;
01542     break;
01543   }
01544 
01545   OutOps.push_back(Op0);
01546   OutOps.push_back(Op1);
01547   return false;
01548 }
01549 
01550 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
01551   unsigned UseCount = 0;
01552   for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
01553     UseCount++;
01554   }
01555 
01556   return (UseCount <= 1);
01557 
01558 }
01559 
01560 //===--------------------------------------------------------------------===//
01561 // Return 'true' if use count of the global address is below threshold.
01562 //===--------------------------------------------------------------------===//
01563 bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const {
01564   assert(N->getOpcode() == ISD::TargetGlobalAddress &&
01565          "Expecting a target global address");
01566 
01567   // Always try to fold the address.
01568   if (TM.getOptLevel() == CodeGenOpt::Aggressive)
01569     return true;
01570 
01571   GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
01572   DenseMap<const GlobalValue *, unsigned>::const_iterator GI =
01573     GlobalAddressUseCountMap.find(GA->getGlobal());
01574 
01575   if (GI == GlobalAddressUseCountMap.end())
01576     return false;
01577 
01578   return GI->second <= MaxNumOfUsesForConstExtenders;
01579 }
01580 
01581 //===--------------------------------------------------------------------===//
01582 // Return true if the non-GP-relative global address can be folded.
01583 //===--------------------------------------------------------------------===//
01584 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
01585   return foldGlobalAddressImpl(N, R, false);
01586 }
01587 
01588 //===--------------------------------------------------------------------===//
01589 // Return true if the GP-relative global address can be folded.
01590 //===--------------------------------------------------------------------===//
01591 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
01592   return foldGlobalAddressImpl(N, R, true);
01593 }
01594 
01595 //===--------------------------------------------------------------------===//
01596 // Fold offset of the global address if number of uses are below threshold.
01597 //===--------------------------------------------------------------------===//
01598 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
01599                                                 bool ShouldLookForGP) {
01600   if (N.getOpcode() == ISD::ADD) {
01601     SDValue N0 = N.getOperand(0);
01602     SDValue N1 = N.getOperand(1);
01603     if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
01604         (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
01605       ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
01606       GlobalAddressSDNode *GA =
01607         dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
01608 
01609       if (Const && GA &&
01610           (GA->getOpcode() == ISD::TargetGlobalAddress)) {
01611         if ((N0.getOpcode() == HexagonISD::CONST32) &&
01612                 !hasNumUsesBelowThresGA(GA))
01613             return false;
01614         R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
01615                                           SDLoc(Const),
01616                                           N.getValueType(),
01617                                           GA->getOffset() +
01618                                           (uint64_t)Const->getSExtValue());
01619         return true;
01620       }
01621     }
01622   }
01623   return false;
01624 }
01625 
01626 bool HexagonDAGToDAGISel::SelectAddrFI(SDValue& N, SDValue &R) {
01627   if (N.getOpcode() != ISD::FrameIndex)
01628     return false;
01629   FrameIndexSDNode *FX = cast<FrameIndexSDNode>(N);
01630   R = CurDAG->getTargetFrameIndex(FX->getIndex(), MVT::i32);
01631   return true;
01632 }
01633 
01634 bool HexagonDAGToDAGISel::isValueExtension(SDValue const &Val,
01635                                            unsigned FromBits, SDValue &Src) {
01636   unsigned Opc = Val.getOpcode();
01637   switch (Opc) {
01638   case ISD::SIGN_EXTEND:
01639   case ISD::ZERO_EXTEND:
01640   case ISD::ANY_EXTEND: {
01641     SDValue const &Op0 = Val.getOperand(0);
01642     EVT T = Op0.getValueType();
01643     if (T.isInteger() && T.getSizeInBits() == FromBits) {
01644       Src = Op0;
01645       return true;
01646     }
01647     break;
01648   }
01649   case ISD::SIGN_EXTEND_INREG:
01650   case ISD::AssertSext:
01651   case ISD::AssertZext:
01652     if (Val.getOperand(0).getValueType().isInteger()) {
01653       VTSDNode *T = cast<VTSDNode>(Val.getOperand(1));
01654       if (T->getVT().getSizeInBits() == FromBits) {
01655         Src = Val.getOperand(0);
01656         return true;
01657       }
01658     }
01659     break;
01660   case ISD::AND: {
01661     // Check if this is an AND with "FromBits" of lower bits set to 1.
01662     uint64_t FromMask = (1 << FromBits) - 1;
01663     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
01664       if (C->getZExtValue() == FromMask) {
01665         Src = Val.getOperand(1);
01666         return true;
01667       }
01668     }
01669     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
01670       if (C->getZExtValue() == FromMask) {
01671         Src = Val.getOperand(0);
01672         return true;
01673       }
01674     }
01675     break;
01676   }
01677   case ISD::OR:
01678   case ISD::XOR: {
01679     // OR/XOR with the lower "FromBits" bits set to 0.
01680     uint64_t FromMask = (1 << FromBits) - 1;
01681     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(0))) {
01682       if ((C->getZExtValue() & FromMask) == 0) {
01683         Src = Val.getOperand(1);
01684         return true;
01685       }
01686     }
01687     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val.getOperand(1))) {
01688       if ((C->getZExtValue() & FromMask) == 0) {
01689         Src = Val.getOperand(0);
01690         return true;
01691       }
01692     }
01693   }
01694   default:
01695     break;
01696   }
01697   return false;
01698 }