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