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