131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- HexagonISelDAGToDAG.cpp - A dag to dag inst selector for Hexagon --===// 2b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 3b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// The LLVM Compiler Infrastructure 4b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 5b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file is distributed under the University of Illinois Open Source 6b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// License. See LICENSE.TXT for details. 7b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 8b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===// 9b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 10b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file defines an instruction selector for the Hexagon target. 11b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 12b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===// 13b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 14b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#define DEBUG_TYPE "hexagon-isel" 15b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonISelLowering.h" 16b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonTargetMachine.h" 17b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Intrinsics.h" 18b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/SelectionDAGISel.h" 19b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/Compiler.h" 20b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/Debug.h" 21b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 22b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumusing namespace llvm; 23b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 24b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 25b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===// 26b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Instruction Selector Implementation 27b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===// 28b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 29b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===--------------------------------------------------------------------===// 30b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine 31b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// instructions for SelectionDAG operations. 32b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// 33b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumnamespace { 34b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumclass HexagonDAGToDAGISel : public SelectionDAGISel { 35b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can 36b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum /// make the right decision when generating code for different targets. 37b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const HexagonSubtarget &Subtarget; 38b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 39b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Keep a reference to HexagonTargetMachine. 40b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum HexagonTargetMachine& TM; 41b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const HexagonInstrInfo *TII; 42b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 43b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumpublic: 44b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine) 45b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum : SelectionDAGISel(targetmachine), 46b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()), 47b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TM(targetmachine), 48b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) { 49b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 50b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 51b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 52b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Select(SDNode *N); 53b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 54b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Complex Pattern Selectors. 55b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2); 56b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2); 57b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2); 58b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2); 59b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset); 60b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2); 61b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset); 62b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2); 63b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2); 64b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2); 65b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 66b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum virtual const char *getPassName() const { 67b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return "Hexagon DAG->DAG Pattern Instruction Selection"; 68b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 69b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 70b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 71b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum /// inline asm expressions. 72b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 73b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum char ConstraintCode, 74b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum std::vector<SDValue> &OutOps); 75b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset); 76b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 77b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectLoad(SDNode *N); 78b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl); 79b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl); 80b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode, 81b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl); 82b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode, 83b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl); 84b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl); 85b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl); 86b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectStore(SDNode *N); 87b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectSHL(SDNode *N); 88b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectSelect(SDNode *N); 89b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectTruncate(SDNode *N); 90b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectMul(SDNode *N); 91b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectZeroExtend(SDNode *N); 92b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectIntrinsicWOChain(SDNode *N); 937517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande SDNode *SelectIntrinsicWChain(SDNode *N); 94b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectConstant(SDNode *N); 957517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande SDNode *SelectConstantFP(SDNode *N); 96b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SelectAdd(SDNode *N); 97b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 98b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Include the pieces autogenerated from the target description. 99b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonGenDAGISel.inc" 100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}; 101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} // end anonymous namespace 102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 104b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// createHexagonISelDag - This pass converts a legalized DAG into a 105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// Hexagon-specific DAG, ready for instruction scheduling. 106b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// 107b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumFunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM) { 108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return new HexagonDAGToDAGISel(TM); 109b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 110b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 111b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool IsS11_0_Offset(SDNode * S) { 112b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ConstantSDNode *N = cast<ConstantSDNode>(S); 113b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 114b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // immS16 predicate - True if the immediate fits in a 16-bit sign extended 115b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // field. 116b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int64_t v = (int64_t)N->getSExtValue(); 117b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return isInt<11>(v); 118b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 119b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 120b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 121b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool IsS11_1_Offset(SDNode * S) { 122b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ConstantSDNode *N = cast<ConstantSDNode>(S); 123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // immS16 predicate - True if the immediate fits in a 16-bit sign extended 125b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // field. 126b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int64_t v = (int64_t)N->getSExtValue(); 127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return isShiftedInt<11,1>(v); 128b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 129b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 130b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 131b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool IsS11_2_Offset(SDNode * S) { 132b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ConstantSDNode *N = cast<ConstantSDNode>(S); 133b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 134b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // immS16 predicate - True if the immediate fits in a 16-bit sign extended 135b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // field. 136b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int64_t v = (int64_t)N->getSExtValue(); 137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return isShiftedInt<11,2>(v); 138b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 140b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 141b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool IsS11_3_Offset(SDNode * S) { 142b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ConstantSDNode *N = cast<ConstantSDNode>(S); 143b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 144b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // immS16 predicate - True if the immediate fits in a 16-bit sign extended 145b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // field. 146b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int64_t v = (int64_t)N->getSExtValue(); 147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return isShiftedInt<11,3>(v); 148b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 150b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool IsU6_0_Offset(SDNode * S) { 152b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ConstantSDNode *N = cast<ConstantSDNode>(S); 153b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 154b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // u6 predicate - True if the immediate fits in a 6-bit unsigned extended 155b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // field. 156b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int64_t v = (int64_t)N->getSExtValue(); 157b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return isUInt<6>(v); 158b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 159b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 160b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 161b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool IsU6_1_Offset(SDNode * S) { 162b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ConstantSDNode *N = cast<ConstantSDNode>(S); 163b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 164b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // u6 predicate - True if the immediate fits in a 6-bit unsigned extended 165b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // field. 166b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int64_t v = (int64_t)N->getSExtValue(); 167b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return isShiftedUInt<6,1>(v); 168b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 169b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 170b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 171b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool IsU6_2_Offset(SDNode * S) { 172b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ConstantSDNode *N = cast<ConstantSDNode>(S); 173b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 174b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // u6 predicate - True if the immediate fits in a 6-bit unsigned extended 175b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // field. 176b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int64_t v = (int64_t)N->getSExtValue(); 177b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return isShiftedUInt<6,2>(v); 178b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 179b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 180b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 181b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Intrinsics that return a a predicate. 182b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic unsigned doesIntrinsicReturnPredicate(unsigned ID) 183b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum{ 184b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum switch (ID) { 185b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum default: 186b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return 0; 187b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpeq: 188b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpgt: 189b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpgtu: 190b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpgtup: 191b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpgtp: 192b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpeqp: 193b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_bitsset: 194b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_bitsclr: 195b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpeqi: 196b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpgti: 197b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpgtui: 198b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpgei: 199b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpgeui: 200b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmplt: 201b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_cmpltu: 202b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_bitsclri: 203b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_and: 204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_or: 205b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_xor: 206b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_andn: 207b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_not: 208b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_orn: 209b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_pxfer_map: 210b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_any8: 211b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_all8: 212b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_A2_vcmpbeq: 213b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_A2_vcmpbgtu: 214b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_A2_vcmpheq: 215b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_A2_vcmphgt: 216b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_A2_vcmphgtu: 217b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_A2_vcmpweq: 218b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_A2_vcmpwgt: 219b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_A2_vcmpwgtu: 220b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_tfrrp: 221b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_S2_tstbit_i: 222b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_S2_tstbit_r: 223b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return 1; 224b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 225b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 226b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 227b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 228b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Intrinsics that have predicate operands. 229b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic unsigned doesIntrinsicContainPredicate(unsigned ID) 230b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum{ 231b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum switch (ID) { 232b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum default: 233b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return 0; 234b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_tfrpr: 235b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::TFR_RsPd; 236b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_and: 237b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::AND_pp; 238b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_xor: 239b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::XOR_pp; 240b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_or: 241b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::OR_pp; 242b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_not: 243ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande return Hexagon::NOT_p; 244b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_any8: 245b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::ANY_pp; 246b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_all8: 247b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::ALL_pp; 248b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_vitpack: 249b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::VITPACK_pp; 250b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_mask: 251b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::MASK_p; 252b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_mux: 253b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::MUX_rr; 254b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 255b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but 256b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // that's how it's mapped in q6protos.h. 257b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_muxir: 258b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::MUX_ri; 259b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 260b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but 261b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // that's how it's mapped in q6protos.h. 262b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_muxri: 263b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::MUX_ir; 264b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 265b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_muxii: 266b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::MUX_ii; 267b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_C2_vmux: 268b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::VMUX_prr64; 269b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_S2_valignrb: 270b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::VALIGN_rrp; 271b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case Intrinsic::hexagon_S2_vsplicerb: 272b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Hexagon::VSPLICE_rrp; 273b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 274b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 275b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 276b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 277b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool OffsetFitsS11(EVT MemType, int64_t Offset) { 278b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) { 279b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 280b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 281b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) { 282b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 283b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 284b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) { 285b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 286b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 287b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (MemType == MVT::i8 && isInt<11>(Offset)) { 288b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 289b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 290b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; 291b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 292b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 293b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 294b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 295b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Try to lower loads of GlobalAdresses into base+offset loads. Custom 296b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// lowering for GlobalAddress nodes has already turned it into a 297b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// CONST32. 298b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 299b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) { 300b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = LD->getChain(); 301b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Const32 = LD->getBasePtr().getNode(); 302b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Opcode = 0; 303b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 304b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Const32->getOpcode() == HexagonISD::CONST32 && 305b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ISD::isNormalLoad(LD)) { 306b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Base = Const32->getOperand(0); 307b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum EVT LoadedVT = LD->getMemoryVT(); 308b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset(); 309b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) { 310b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT PointerTy = TLI.getPointerTy(); 311b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const GlobalValue* GV = 312b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<GlobalAddressSDNode>(Base)->getGlobal(); 313b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargAddr = 314b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0); 3155262abb2682a4d09cda3563a55f27caffb57466cBrendon Cahoon SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set, 3165262abb2682a4d09cda3563a55f27caffb57466cBrendon Cahoon dl, PointerTy, 3175262abb2682a4d09cda3563a55f27caffb57466cBrendon Cahoon TargAddr); 318b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Figure out base + offset opcode 319b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed; 320b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed; 321b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed; 322b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed; 32326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else llvm_unreachable("unknown memory type"); 324b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 325b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Build indexed load. 326b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy); 327b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result = CurDAG->getMachineNode(Opcode, dl, 328b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getValueType(0), 329b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, 330b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(NewBase,0), 331b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TargetConstOff, 332b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Chain); 333b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 334b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = LD->getMemOperand(); 335b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 336b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(LD, Result); 337b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 338b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 339b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 340b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 341b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(LD); 342b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 343b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 344b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 345b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD, 346b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Opcode, 347b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl) 348b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum{ 349b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = LD->getChain(); 350b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum EVT LoadedVT = LD->getMemoryVT(); 351b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Base = LD->getBasePtr(); 352b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Offset = LD->getOffset(); 353b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *OffsetNode = Offset.getNode(); 354b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 355b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N1 = LD->getOperand(1); 356b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue CPTmpN1_0; 357b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue CPTmpN1_1; 358b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) && 359b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum N1.getNode()->getValueType(0) == MVT::i32) { 360b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (TII->isValidAutoIncImm(LoadedVT, Val)) { 361b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32); 362b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32, 363b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, Base, TargetConst, 364b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Chain); 365b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64, 366b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 0)); 367b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 368b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = LD->getMemOperand(); 369b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 370b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Froms[] = { SDValue(LD, 0), 371b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 1), 372b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 2) 373b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 374b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Tos[] = { SDValue(Result_2, 0), 375b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 1), 376b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 2) 377b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 378b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(Froms, Tos, 3); 379b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result_2; 38071d56462a1bc885c97321eff2fc4b481fd3bf452Sirish Pande } 381b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 382b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 383b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 384b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, Base, TargetConst0, 385b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Chain); 386b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, 387b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i64, SDValue(Result_1, 0)); 388b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, 389b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, Base, TargetConstVal, 390b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 1)); 391b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 392b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = LD->getMemOperand(); 393b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 394b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Froms[] = { SDValue(LD, 0), 395b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 1), 396b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 2) 397b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 398b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Tos[] = { SDValue(Result_2, 0), 399b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_3, 0), 400b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 1) 401b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 402b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(Froms, Tos, 3); 403b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result_2; 404b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 405b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(LD); 406b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 407b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 408b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 409b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD, 410b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Opcode, 411b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl) 412b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum{ 413b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = LD->getChain(); 414b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum EVT LoadedVT = LD->getMemoryVT(); 415b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Base = LD->getBasePtr(); 416b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Offset = LD->getOffset(); 417b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *OffsetNode = Offset.getNode(); 418b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 419b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N1 = LD->getOperand(1); 420b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue CPTmpN1_0; 421b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue CPTmpN1_1; 422b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) && 423b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum N1.getNode()->getValueType(0) == MVT::i32) { 424b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (TII->isValidAutoIncImm(LoadedVT, Val)) { 425b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 426b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 427b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 428b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, MVT::Other, Base, 429b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TargetConstVal, Chain); 430b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32, 431b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TargetConst0); 432b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl, 433b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i64, MVT::Other, 434b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_2,0), 435b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1,0)); 436b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 437b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = LD->getMemOperand(); 438b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 439b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Froms[] = { SDValue(LD, 0), 440b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 1), 441b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 2) 442b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 443b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Tos[] = { SDValue(Result_3, 0), 444b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 1), 445b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 2) 446b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 447b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(Froms, Tos, 3); 448b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result_3; 449b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 450b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 451b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Generate an indirect load. 452b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 453b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 454b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 455b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, 456b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base, TargetConst0, Chain); 457b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32, 458b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TargetConst0); 459b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl, 460b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i64, MVT::Other, 461b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_2,0), 462b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1,0)); 463b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Add offset to base. 464b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32, 465b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base, TargetConstVal, 466b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 1)); 467b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 468b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = LD->getMemOperand(); 469b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 470b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Froms[] = { SDValue(LD, 0), 471b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 1), 472b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 2) 473b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 474b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Tos[] = { SDValue(Result_3, 0), // Load value. 475b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_4, 0), // New address. 476b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 1) 477b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 478b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(Froms, Tos, 3); 479b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result_3; 480b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 481b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 482b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(LD); 483b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 484b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 485b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 486b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) { 487b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = LD->getChain(); 488b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Base = LD->getBasePtr(); 489b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Offset = LD->getOffset(); 490b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *OffsetNode = Offset.getNode(); 491b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Get the constant value. 492b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 493b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum EVT LoadedVT = LD->getMemoryVT(); 494b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Opcode = 0; 495b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 496b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Check for zero ext loads. 497b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD); 498b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 499b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Figure out the opcode. 500b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (LoadedVT == MVT::i64) { 501b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (TII->isValidAutoIncImm(LoadedVT, Val)) 502b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Opcode = Hexagon::POST_LDrid; 503b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else 504b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Opcode = Hexagon::LDrid; 505b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else if (LoadedVT == MVT::i32) { 506b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (TII->isValidAutoIncImm(LoadedVT, Val)) 507b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Opcode = Hexagon::POST_LDriw; 508b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else 509b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Opcode = Hexagon::LDriw; 510b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else if (LoadedVT == MVT::i16) { 511b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (TII->isValidAutoIncImm(LoadedVT, Val)) 512b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih; 513b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else 514b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih; 515b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else if (LoadedVT == MVT::i8) { 516b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (TII->isValidAutoIncImm(LoadedVT, Val)) 517b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib; 518b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else 519b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib; 520b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else 52126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande llvm_unreachable("unknown memory type"); 522b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 523b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // For zero ext i64 loads, we need to add combine instructions. 524b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (LD->getValueType(0) == MVT::i64 && 525b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getExtensionType() == ISD::ZEXTLOAD) { 526b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectIndexedLoadZeroExtend64(LD, Opcode, dl); 527b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 528b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (LD->getValueType(0) == MVT::i64 && 529b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getExtensionType() == ISD::SEXTLOAD) { 530b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Handle sign ext i64 loads. 531b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectIndexedLoadSignExtend64(LD, Opcode, dl); 532b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 533b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (TII->isValidAutoIncImm(LoadedVT, Val)) { 534b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 535b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result = CurDAG->getMachineNode(Opcode, dl, 536b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getValueType(0), 537b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, MVT::Other, Base, 538b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TargetConstVal, Chain); 539b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 540b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = LD->getMemOperand(); 541b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 542b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Froms[] = { SDValue(LD, 0), 543b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 1), 544b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 2) 545b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 546b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Tos[] = { SDValue(Result, 0), 547b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result, 1), 548b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result, 2) 549b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 550b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(Froms, Tos, 3); 551b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 552b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 553b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 554b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 555b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, 556b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getValueType(0), 557b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, Base, TargetConst0, 558b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Chain); 559b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32, 560b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base, TargetConstVal, 561b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 1)); 562b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 563b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = LD->getMemOperand(); 564b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 565b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Froms[] = { SDValue(LD, 0), 566b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 1), 567b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(LD, 2) 568b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 569b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const SDValue Tos[] = { SDValue(Result_1, 0), 570b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_2, 0), 571b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 1) 572b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }; 573b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(Froms, Tos, 3); 574b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result_1; 575b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 576b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 577b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 578b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 579b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) { 580b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *result; 581b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 582b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LoadSDNode *LD = cast<LoadSDNode>(N); 583b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ISD::MemIndexedMode AM = LD->getAddressingMode(); 584b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 585b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Handle indexed loads. 586b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (AM != ISD::UNINDEXED) { 587b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum result = SelectIndexedLoad(LD, dl); 588b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 589b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum result = SelectBaseOffsetLoad(LD, dl); 590b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 591b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 592b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return result; 593b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 594b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 595b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 596b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) { 597b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = ST->getChain(); 598b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Base = ST->getBasePtr(); 599b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Offset = ST->getOffset(); 600b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Value = ST->getValue(); 601b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *OffsetNode = Offset.getNode(); 602b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Get the constant value. 603b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 604b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum EVT StoredVT = ST->getMemoryVT(); 605b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 606b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Offset value must be within representable range 607b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // and must have correct alignment properties. 608b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (TII->isValidAutoIncImm(StoredVT, Val)) { 609b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Ops[] = { Value, Base, 610b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum CurDAG->getTargetConstant(Val, MVT::i32), Chain}; 611b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Opcode = 0; 612b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 613b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Figure out the post inc version of opcode. 614b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri; 615b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri; 616b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri; 617b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri; 61826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else llvm_unreachable("unknown memory type"); 619b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 620b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Build post increment store. 621b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 622b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, Ops, 4); 623b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 624b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = ST->getMemOperand(); 625b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 626b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 627b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(ST, Result); 628b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(SDValue(ST,1), SDValue(Result,1)); 629b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 630b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 631b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 632b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Note: Order of operands matches the def of instruction: 633b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ... 634b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // and it differs for POST_ST* for instance. 635b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value, 636b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Chain}; 637b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Opcode = 0; 638b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 639b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Figure out the opcode. 640b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (StoredVT == MVT::i64) Opcode = Hexagon::STrid; 64126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed; 642b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih; 643b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib; 64426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else llvm_unreachable("unknown memory type"); 645b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 646b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Build regular store. 647b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 648b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops, 649b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 4); 650b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Build splitted incriment instruction. 651b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32, 652b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base, 653b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TargetConstVal, 654b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 0)); 655b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 656b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = ST->getMemOperand(); 657b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 658b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 659b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(SDValue(ST,0), SDValue(Result_2,0)); 660b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(SDValue(ST,1), SDValue(Result_1,0)); 661b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result_2; 662b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 663b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 664b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 665b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST, 666b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl) { 667b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = ST->getChain(); 668b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Const32 = ST->getBasePtr().getNode(); 669b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Value = ST->getValue(); 670b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned Opcode = 0; 671b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 672b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Try to lower stores of GlobalAdresses into indexed stores. Custom 673b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // lowering for GlobalAddress nodes has already turned it into a 674b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // CONST32. Avoid truncating stores for the moment. Post-inc stores 675b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // do the same. Don't think there's a reason for it, so will file a 676b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // bug to fix. 677b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if ((Const32->getOpcode() == HexagonISD::CONST32) && 678b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) { 679b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Base = Const32->getOperand(0); 680b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Base.getOpcode() == ISD::TargetGlobalAddress) { 681b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum EVT StoredVT = ST->getMemoryVT(); 682b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset(); 683b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) { 684b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT PointerTy = TLI.getPointerTy(); 685b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const GlobalValue* GV = 686b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<GlobalAddressSDNode>(Base)->getGlobal(); 687b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargAddr = 688b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0); 6895262abb2682a4d09cda3563a55f27caffb57466cBrendon Cahoon SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set, 6905262abb2682a4d09cda3563a55f27caffb57466cBrendon Cahoon dl, PointerTy, 6915262abb2682a4d09cda3563a55f27caffb57466cBrendon Cahoon TargAddr); 692b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 693b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Figure out base + offset opcode 694b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed; 695b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed; 696b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed; 697b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed; 69826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else llvm_unreachable("unknown memory type"); 699b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 700b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Ops[] = {SDValue(NewBase,0), 701b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum CurDAG->getTargetConstant(Offset,PointerTy), 702b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Value, Chain}; 703b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // build indexed store 704b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result = CurDAG->getMachineNode(Opcode, dl, 705b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, Ops, 4); 706b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 707b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MemOp[0] = ST->getMemOperand(); 708b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 709b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(ST, Result); 710b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 711b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 712b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 713b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 714b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 715b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(ST); 716b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 717b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 718b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 719b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) { 720b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 721b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum StoreSDNode *ST = cast<StoreSDNode>(N); 722b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ISD::MemIndexedMode AM = ST->getAddressingMode(); 723b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 724b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Handle indexed stores. 725b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (AM != ISD::UNINDEXED) { 726b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectIndexedStore(ST, dl); 727b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 72871d56462a1bc885c97321eff2fc4b481fd3bf452Sirish Pande 729b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectBaseOffsetStore(ST, dl); 730b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 731b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 732b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) { 733b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 734b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 735b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 736b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %conv.i = sext i32 %tmp1 to i64 737b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %conv2.i = sext i32 %add to i64 738b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %mul.i = mul nsw i64 %conv2.i, %conv.i 739b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 740b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // --- match with the following --- 741b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 742b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %mul.i = mpy (%tmp1, %add) 743b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 744b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 745b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N->getValueType(0) == MVT::i64) { 746b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Shifting a i64 signed multiply. 747b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue MulOp0 = N->getOperand(0); 748b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue MulOp1 = N->getOperand(1); 749b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 750b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue OP0; 751b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue OP1; 752b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 753b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Handle sign_extend and sextload. 754b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) { 755b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Sext0 = MulOp0.getOperand(0); 756b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Sext0.getNode()->getValueType(0) != MVT::i32) { 75726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return SelectCode(N); 758b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 759b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 760b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP0 = Sext0; 761b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else if (MulOp0.getOpcode() == ISD::LOAD) { 762b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode()); 763b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (LD->getMemoryVT() != MVT::i32 || 764b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getExtensionType() != ISD::SEXTLOAD || 765b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getAddressingMode() != ISD::UNINDEXED) { 76626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return SelectCode(N); 767b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 768b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 769b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = LD->getChain(); 770b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 771b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 772b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, 773b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getBasePtr(), TargetConst0, 774b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Chain), 0); 775b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 776b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 777b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 778b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 779b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Same goes for the second operand. 780b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) { 781b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Sext1 = MulOp1.getOperand(0); 782b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Sext1.getNode()->getValueType(0) != MVT::i32) { 783b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 784b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 785b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 786b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP1 = Sext1; 787b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else if (MulOp1.getOpcode() == ISD::LOAD) { 788b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode()); 789b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (LD->getMemoryVT() != MVT::i32 || 790b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getExtensionType() != ISD::SEXTLOAD || 791b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getAddressingMode() != ISD::UNINDEXED) { 792b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 793b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 794b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 795b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = LD->getChain(); 796b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 797b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 798b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, 799b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getBasePtr(), TargetConst0, 800b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Chain), 0); 801b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 802b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 803b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 804b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 805b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Generate a mpy instruction. 806b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64, 807b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP0, OP1); 808b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result); 809b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 810b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 811b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 812b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 813b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 814b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 815b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 816b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) { 817b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 818b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N0 = N->getOperand(0); 819b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N0.getOpcode() == ISD::SETCC) { 820b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N00 = N0.getOperand(0); 821b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) { 822b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N000 = N00.getOperand(0); 823b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N001 = N00.getOperand(1); 824b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (cast<VTSDNode>(N001)->getVT() == MVT::i16) { 825b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N01 = N0.getOperand(1); 826b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N02 = N0.getOperand(2); 827b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 828b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2, 829b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1, 830b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // IntRegs:i32:$src2) 831b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2) 832b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Pattern complexity = 9 cost = 1 size = 0. 833b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) { 834b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N1 = N->getOperand(1); 835b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N01 == N1) { 836b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N2 = N->getOperand(2); 837b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N000 == N2 && 838b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 && 839b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) { 840b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl, 841b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, N000); 842b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl, 843b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, 844b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(SextNode, 0), 845b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum N1); 846b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result); 847b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 848b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 849b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 850b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 851b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 852b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2, 853b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1, 854b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // IntRegs:i32:$src2) 855b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2) 856b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Pattern complexity = 9 cost = 1 size = 0. 857b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) { 858b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N1 = N->getOperand(1); 859b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N01 == N1) { 860b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue N2 = N->getOperand(2); 861b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N000 == N2 && 862b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 && 863b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) { 864b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl, 865b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, N000); 866b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl, 867b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, 868b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(SextNode, 0), 869b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum N1); 870b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result); 871b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 872b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 873b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 874b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 875b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 876b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 877b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 878b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 879b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 880b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 881b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 882b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 883b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) { 884b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 885b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Shift = N->getOperand(0); 886b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 887b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 888b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %conv.i = sext i32 %tmp1 to i64 889b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %conv2.i = sext i32 %add to i64 890b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %mul.i = mul nsw i64 %conv2.i, %conv.i 891b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %shr5.i = lshr i64 %mul.i, 32 892b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %conv3.i = trunc i64 %shr5.i to i32 893b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 894b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // --- match with the following --- 895b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 896b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // %conv3.i = mpy (%tmp1, %add) 897b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // 898b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Trunc to i32. 899b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N->getValueType(0) == MVT::i32) { 900b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Trunc from i64. 901b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Shift.getNode()->getValueType(0) == MVT::i64) { 902b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Trunc child is logical shift right. 903b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Shift.getOpcode() != ISD::SRL) { 904b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 905b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 906b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 907b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue ShiftOp0 = Shift.getOperand(0); 908b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue ShiftOp1 = Shift.getOperand(1); 909b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 910b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Shift by const 32 911b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (ShiftOp1.getOpcode() != ISD::Constant) { 912b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 913b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 914b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 915b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t ShiftConst = 916b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue(); 917b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (ShiftConst != 32) { 918b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 919b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 920b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 921b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Shifting a i64 signed multiply 922b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Mul = ShiftOp0; 923b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Mul.getOpcode() != ISD::MUL) { 924b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 925b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 926b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 927b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue MulOp0 = Mul.getOperand(0); 928b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue MulOp1 = Mul.getOperand(1); 929b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 930b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue OP0; 931b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue OP1; 932b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 933b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Handle sign_extend and sextload 934b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) { 935b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Sext0 = MulOp0.getOperand(0); 936b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Sext0.getNode()->getValueType(0) != MVT::i32) { 937b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 938b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 939b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 940b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP0 = Sext0; 941b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else if (MulOp0.getOpcode() == ISD::LOAD) { 942b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode()); 943b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (LD->getMemoryVT() != MVT::i32 || 944b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getExtensionType() != ISD::SEXTLOAD || 945b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getAddressingMode() != ISD::UNINDEXED) { 946b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 947b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 948b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 949b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = LD->getChain(); 950b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 951b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 952b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, 953b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getBasePtr(), 954b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TargetConst0, Chain), 0); 955b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 956b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 957b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 958b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 959b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Same goes for the second operand. 960b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) { 961b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Sext1 = MulOp1.getOperand(0); 962b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Sext1.getNode()->getValueType(0) != MVT::i32) 963b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 964b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 965b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP1 = Sext1; 966b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else if (MulOp1.getOpcode() == ISD::LOAD) { 967b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode()); 968b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (LD->getMemoryVT() != MVT::i32 || 969b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getExtensionType() != ISD::SEXTLOAD || 970b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getAddressingMode() != ISD::UNINDEXED) { 971b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 972b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 973b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 974b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Chain = LD->getChain(); 975b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 976b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 977b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::Other, 978b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum LD->getBasePtr(), 979b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TargetConst0, Chain), 0); 980b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 981b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 982b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 983b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 984b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Generate a mpy instruction. 985b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32, 986b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OP0, OP1); 987b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result); 988b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 989b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 990b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 991b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 992b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 993b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 994b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 995b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 996b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) { 997b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 998b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N->getValueType(0) == MVT::i32) { 999b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Shl_0 = N->getOperand(0); 1000b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Shl_1 = N->getOperand(1); 1001b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // RHS is const. 1002b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Shl_1.getOpcode() == ISD::Constant) { 1003b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Shl_0.getOpcode() == ISD::MUL) { 1004b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Mul_0 = Shl_0.getOperand(0); // Val 1005b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Mul_1 = Shl_0.getOperand(1); // Const 1006b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // RHS of mul is const. 1007b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Mul_1.getOpcode() == ISD::Constant) { 1008b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t ShlConst = 1009b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue(); 1010b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t MulConst = 1011b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue(); 1012b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t ValConst = MulConst << ShlConst; 1013b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Val = CurDAG->getTargetConstant(ValConst, 1014b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32); 1015b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode())) 1016b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (isInt<9>(CN->getSExtValue())) { 1017b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result = 1018b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, 1019b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, Mul_0, Val); 1020b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result); 1021b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 1022b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1023b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1024b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1025b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else if (Shl_0.getOpcode() == ISD::SUB) { 1026b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Sub_0 = Shl_0.getOperand(0); // Const 0 1027b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Sub_1 = Shl_0.getOperand(1); // Val 1028b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Sub_0.getOpcode() == ISD::Constant) { 1029b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t SubConst = 1030b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue(); 1031b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (SubConst == 0) { 1032b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Sub_1.getOpcode() == ISD::SHL) { 1033b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Shl2_0 = Sub_1.getOperand(0); // Val 1034b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Shl2_1 = Sub_1.getOperand(1); // Const 1035b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Shl2_1.getOpcode() == ISD::Constant) { 1036b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t ShlConst = 1037b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue(); 1038b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t Shl2Const = 1039b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue(); 1040b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t ValConst = 1 << (ShlConst+Shl2Const); 1041b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32); 1042b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (ConstantSDNode *CN = 1043b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum dyn_cast<ConstantSDNode>(Val.getNode())) 1044b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (isInt<9>(CN->getSExtValue())) { 1045b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result = 1046b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32, 1047b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Shl2_0, Val); 1048b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result); 1049b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 1050b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1051b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1052b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1053b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1054b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1055b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1056b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1057b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1058b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 1059b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1060b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1061b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1062b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1063b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// If there is an zero_extend followed an intrinsic in DAG (this means - the 1064b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// result of the intrinsic is predicate); convert the zero_extend to 1065b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// transfer instruction. 1066b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1067b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Zero extend -> transfer is lowered here. Otherwise, zero_extend will be 1068b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// converted into a MUX as predicate registers defined as 1 bit in the 1069b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// compiler. Architecture defines them as 8-bit registers. 1070b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// We want to preserve all the lower 8-bits and, not just 1 LSB bit. 1071b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1072b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) { 1073b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 1074b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *IsIntrinsic = N->getOperand(0).getNode(); 1075b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) { 1076b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned ID = 1077b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue(); 1078b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (doesIntrinsicReturnPredicate(ID)) { 1079b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Now we need to differentiate target data types. 1080b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N->getValueType(0) == MVT::i64) { 1081b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs). 1082b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 1083b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl, 1084b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, 1085b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(IsIntrinsic, 0)); 1086b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, 1087b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, 1088b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum TargetConst0); 1089b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl, 1090b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i64, MVT::Other, 1091b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_2, 0), 1092b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Result_1, 0)); 1093b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result_3); 1094b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result_3; 1095b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1096b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N->getValueType(0) == MVT::i32) { 1097b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Convert the zero_extend to Rs = Pd 1098b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl, 1099b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum MVT::i32, 1100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(IsIntrinsic, 0)); 1101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, RsPd); 1102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return RsPd; 1103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1104bc2198133a1836598b54b943420748e75d5dea94Craig Topper llvm_unreachable("Unexpected value type"); 1105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1106b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1107b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 1108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1109b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1110b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1111b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1112b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Checking for intrinsics which have predicate registers as operand(s) 1113b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// and lowering to the actual intrinsic. 1114b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1115b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) { 1116b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 1117b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 1118b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID); 1119b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1120b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // We are concerned with only those intrinsics that have predicate registers 1121b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // as at least one of the operands. 1122b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (IntrinsicWithPred) { 1123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SmallVector<SDValue, 8> Ops; 1124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const MCInstrDesc &MCID = TII->get(IntrinsicWithPred); 1125b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum const TargetRegisterInfo *TRI = TM.getRegisterInfo(); 1126b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Iterate over all the operands of the intrinsics. 1128b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // For PredRegs, do the transfer. 1129b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // For Double/Int Regs, just preserve the value 1130b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // For immediates, lower it. 1131b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum for (unsigned i = 1; i < N->getNumOperands(); ++i) { 1132b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Arg = N->getOperand(i).getNode(); 1133397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund Olesen const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF); 1134b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1135420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper if (RC == &Hexagon::IntRegsRegClass || 1136420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC == &Hexagon::DoubleRegsRegClass) { 1137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Ops.push_back(SDValue(Arg, 0)); 1138420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper } else if (RC == &Hexagon::PredRegsRegClass) { 1139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Do the transfer. 1140b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1, 1141b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Arg, 0)); 1142b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Ops.push_back(SDValue(PdRs,0)); 1143b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) { 1144b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // This is immediate operand. Lower it here making sure that we DO have 1145b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // const SDNode for immediate value. 1146b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue(); 1147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32); 1148b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Ops.push_back(SDVal); 1149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } else { 1150bc2198133a1836598b54b943420748e75d5dea94Craig Topper llvm_unreachable("Unimplemented"); 1151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1152b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1153b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum EVT ReturnValueVT = N->getValueType(0); 1154b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl, 1155b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReturnValueVT, 1156b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Ops.data(), Ops.size()); 1157b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result); 1158b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 1159b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1160b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 1161b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1162b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 11637517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande// 11647517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande// Map floating point constant values. 11657517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande// 11667517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish PandeSDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) { 11677517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande DebugLoc dl = N->getDebugLoc(); 11687517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N); 11697517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande APFloat APF = CN->getValueAPF(); 11707517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande if (N->getValueType(0) == MVT::f32) { 11717517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32, 11727517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32)); 11737517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande } 11747517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande else if (N->getValueType(0) == MVT::f64) { 11757517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64, 11767517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64)); 11777517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande } 11787517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande 11797517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande return SelectCode(N); 11807517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande} 11817517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande 1182b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1183b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1184b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Map predicate true (encoded as -1 in LLVM) to a XOR. 1185b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1186b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) { 1187b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 1188b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N->getValueType(0) == MVT::i1) { 1189b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Result; 1190b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum int32_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 1191b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Val == -1) { 1192b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Create the IntReg = 1 node. 1193b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* IntRegTFR = 1194b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32, 1195b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum CurDAG->getTargetConstant(0, MVT::i32)); 1196b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1197b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Pd = IntReg 1198b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1, 1199b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(IntRegTFR, 0)); 1200b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1201b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // not(Pd) 1202ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1, 1203b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Pd, 0)); 1204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1205b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // xor(not(Pd)) 1206b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1, 1207b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue(Pd, 0), SDValue(NotPd, 0)); 1208b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1209b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // We have just built: 1210b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Rs = Pd 1211b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Pd = xor(not(Pd), Pd) 1212b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1213b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result); 1214b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 1215b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1216b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1217b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1218b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 1219b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1220b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1221b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1222b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1223b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Map add followed by a asr -> asr +=. 1224b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1225b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) { 1226b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum DebugLoc dl = N->getDebugLoc(); 1227b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N->getValueType(0) != MVT::i32) { 1228b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 1229b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1230b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Identify nodes of the form: add(asr(...)). 1231b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDNode* Src1 = N->getOperand(0).getNode(); 1232b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse() 1233b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum || Src1->getValueType(0) != MVT::i32) { 1234b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 1235b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1236b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1237b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that 1238b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum // Rd and Rd' are assigned to the same register 123971d56462a1bc885c97321eff2fc4b481fd3bf452Sirish Pande SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32, 1240b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum N->getOperand(1), 1241b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Src1->getOperand(0), 1242b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Src1->getOperand(1)); 1243b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum ReplaceUses(N, Result); 1244b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1245b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return Result; 1246b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1247b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1248b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1249b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSDNode *HexagonDAGToDAGISel::Select(SDNode *N) { 1250b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (N->isMachineOpcode()) 1251b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return NULL; // Already selected. 1252b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1253b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1254b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum switch (N->getOpcode()) { 1255b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::Constant: 1256b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectConstant(N); 1257b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 12587517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande case ISD::ConstantFP: 12597517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande return SelectConstantFP(N); 12607517bbc91ae1c60d3c7df8b11642c7a5bb3d5a71Sirish Pande 1261b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::ADD: 1262b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectAdd(N); 1263b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1264b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::SHL: 1265b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectSHL(N); 1266b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1267b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::LOAD: 1268b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectLoad(N); 1269b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1270b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::STORE: 1271b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectStore(N); 1272b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1273b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::SELECT: 1274b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectSelect(N); 1275b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1276b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::TRUNCATE: 1277b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectTruncate(N); 1278b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1279b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::MUL: 1280b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectMul(N); 1281b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1282b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::ZERO_EXTEND: 1283b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectZeroExtend(N); 1284b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1285b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case ISD::INTRINSIC_WO_CHAIN: 1286b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectIntrinsicWOChain(N); 1287b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1288b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1289b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectCode(N); 1290b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1291b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1292b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1293b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1294b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way 1295b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// to define these instructions. 1296b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// 1297b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base, 1298b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Offset) { 1299b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1300b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1301b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1302b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1303b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1304b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1305b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1306b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1307b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1308b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr; 1309b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1310b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1311b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1312b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1313b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1314b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base, 1315b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Offset) { 1316b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1317b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1318b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1319b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1320b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1321b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1322b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1323b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsS11_0_Offset(Offset.getNode())); 1324b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1325b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr; 1326b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1327b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsS11_0_Offset(Offset.getNode())); 1328b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1329b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1330b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1331b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base, 1332b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Offset) { 1333b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1334b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1335b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1336b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1337b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1338b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1339b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1340b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsS11_1_Offset(Offset.getNode())); 1341b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1342b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr; 1343b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1344b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsS11_1_Offset(Offset.getNode())); 1345b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1346b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1347b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1348b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base, 1349b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Offset) { 1350b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1351b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1352b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1353b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1354b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1355b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1356b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1357b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsS11_2_Offset(Offset.getNode())); 1358b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1359b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr; 1360b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1361b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsS11_2_Offset(Offset.getNode())); 1362b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1363b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1364b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1365b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base, 1366b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Offset) { 1367b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1368b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1369b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1370b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1371b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1372b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1373b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1374b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsU6_0_Offset(Offset.getNode())); 1375b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1376b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr; 1377b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1378b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsU6_0_Offset(Offset.getNode())); 1379b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1380b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1381b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1382b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base, 1383b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Offset) { 1384b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1385b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1386b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1387b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1388b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1389b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1390b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1391b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsU6_1_Offset(Offset.getNode())); 1392b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1393b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr; 1394b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1395b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsU6_1_Offset(Offset.getNode())); 1396b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1397b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1398b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1399b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base, 1400b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Offset) { 1401b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1402b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1403b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1404b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1405b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1406b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1407b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1408b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsU6_2_Offset(Offset.getNode())); 1409b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1410b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr; 1411b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1412b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsU6_2_Offset(Offset.getNode())); 1413b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1414b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1415b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1416b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base, 1417b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Offset) { 1418b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1419b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() != ISD::ADD) { 1420b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return(SelectADDRriS11_2(Addr, Base, Offset)); 1421b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1422b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1423b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return SelectADDRriS11_2(Addr, Base, Offset); 1424b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1425b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1426b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1427b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base, 1428b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Offset) { 1429b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1430b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1431b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1432b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1433b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1434b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1435b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1436b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsS11_3_Offset(Offset.getNode())); 1437b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1438b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr; 1439b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1440b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return (IsS11_3_Offset(Offset.getNode())); 1441b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1442b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1443b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, 1444b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &R2) { 1445b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::FrameIndex) return false; 1446b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1447b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1448b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1449b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1450b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::ADD) { 1451b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 1452b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (isInt<13>(CN->getSExtValue())) 1453b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Let the reg+imm pattern catch this! 1454b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum R1 = Addr.getOperand(0); 1455b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum R2 = Addr.getOperand(1); 1456b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1457b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1458b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1459b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum R1 = Addr; 1460b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1461b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1462b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1463b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1464b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1465b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Handle generic address case. It is accessed from inlined asm =m constraints, 1466b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// which could have any kind of pointer. 1467b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr, 1468b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue &Base, SDValue &Offset) { 1469b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1470b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Addr.getOpcode() == ISD::TargetGlobalAddress) 1471b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; // Direct calls. 1472b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1473b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1474b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1475b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1476b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1477b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1478b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1479b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (Addr.getOpcode() == ISD::ADD) { 1480b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr.getOperand(0); 1481b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = Addr.getOperand(1); 1482b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1483b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1484b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1485b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Base = Addr; 1486b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum Offset = CurDAG->getTargetConstant(0, MVT::i32); 1487b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1488b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1489b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1490b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1491b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonDAGToDAGISel:: 1492b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 1493b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum std::vector<SDValue> &OutOps) { 1494b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum SDValue Op0, Op1; 1495b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1496b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum switch (ConstraintCode) { 1497b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case 'o': // Offsetable. 1498b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case 'v': // Not offsetable. 1499b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum default: return true; 1500b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum case 'm': // Memory. 1501b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (!SelectAddr(Op.getNode(), Op, Op0, Op1)) 1502b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return true; 1503b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum break; 1504b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum } 1505b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum 1506b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OutOps.push_back(Op0); 1507b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum OutOps.push_back(Op1); 1508b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum return false; 1509b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} 1510