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