LLVM API Documentation
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 = static_cast<const HexagonInstrInfo *>( 00450 TM.getSubtargetImpl()->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 = static_cast<const HexagonInstrInfo *>( 00517 TM.getSubtargetImpl()->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 = static_cast<const HexagonInstrInfo *>( 00595 TM.getSubtargetImpl()->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 = static_cast<const HexagonInstrInfo *>( 00705 TM.getSubtargetImpl()->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 = static_cast<const HexagonInstrInfo *>( 01222 TM.getSubtargetImpl()->getInstrInfo()); 01223 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred); 01224 const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->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 }